diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 68ecec81c43..8bb77caf146 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -40,3 +40,6 @@ beeac076c0b9f0a8aaa1424ef1d6df3a6fa8f6ab # use prettier to force lf line endings 7bee4cbeebb91dea4bf438af44509573948e6a56 + +# update prettier version +98d5fe7f7cc1d49ec613086b3a15523087daa213 diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 32df0ce9543..9d2a66b45f4 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -26,9 +26,7 @@ jobs: with: fetch-depth: 0 - # nodejs is needed because the dynamic download of it via the prettier maven plugin often - # times out - # Example: https://github.com/opentripplanner/OpenTripPlanner/actions/runs/4490450225/jobs/7897533439 + # nodejs is needed because Spotless runs Prettier through node/npm - uses: actions/setup-node@v6 with: node-version: 24 @@ -46,9 +44,8 @@ jobs: # to Maven Central open which then hang during the package phase because the Azure (Github Actions) # NAT drops them # https://github.com/actions/runner-images/issues/1499 - # we set nodePath and npmPath to skip downloading the node binary, which frequently times out run: | - mvn jacoco:prepare-agent test jacoco:report -P prettierCheck,unit-tests -Dprettier.nodePath=node -Dprettier.npmPath=npm + mvn jacoco:prepare-agent test jacoco:report -P prettierCheck,unit-tests mvn package -Dmaven.test.skip -P prettierSkip,checkstyleSkip - name: Send coverage data to codecov.io diff --git a/.prettierrc.yml b/.prettierrc.yml deleted file mode 100644 index 161fbd45779..00000000000 --- a/.prettierrc.yml +++ /dev/null @@ -1,14 +0,0 @@ -# Prettier configuration -overrides: - - files: - - "*.java" - options: - printWidth: 100 - tabWidth: 2 - useTabs: false - endOfLine: lf - - files: - - "*.md" - options: - proseWrap: always - printWidth: 100 diff --git a/CLAUDE.md b/CLAUDE.md index 4cdbd57b20f..3d9f7c76a86 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -33,11 +33,15 @@ mvn clean -Pclean-test-snapshots ## Code Formatting & Quality -Quality gates run in the Maven `validate` phase and fail the build on violations: - -- **Prettier** auto-formats Java (`.prettierrc.yml`: 100-char width, 2-space indent). CI enforces - it; check with `mvn prettier:check`. Skip locally with `-Dps`. -- **Checkstyle** runs against `checkstyle.xml`. Skip with `-Dcs` (or `-PcheckstyleSkip`). +Quality gates run in the Maven `validate` / `process-sources` phases and fail the build on +violations: + +- **Prettier**, run through the **Spotless** Maven plugin, auto-formats Java (100-char width, + 2-space indent; the options are configured in the root `pom.xml`). Spotless also removes unused + imports (Javadoc-only references are kept). Requires `node`/`npm` on the `PATH`. CI enforces it; + check with `mvn spotless:check`, format with `mvn spotless:apply`. Skip locally with `-Dps`. +- **Checkstyle** runs against `checkstyle.xml` in the `process-sources` phase (after Spotless). Skip + with `-Dcs` (or `-PcheckstyleSkip`). OpenRewrite (recipes in `openrewrite.yml`, e.g. removing unused imports) does **not** run automatically — invoke it explicitly with `mvn validate -Prewrite` (or the `-Drw` shortcut). diff --git a/application/pom.xml b/application/pom.xml index b8494ec10e9..08d9d86d382 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -294,7 +294,7 @@ org.onebusaway onebusaway-gtfs - 14.2.1 + 14.2.2 @@ -343,7 +343,7 @@ com.hivemq hivemq-mqtt-client - 1.3.17 + 1.4.0 io.github.ci-cmg @@ -363,12 +363,12 @@ com.azure azure-messaging-servicebus - 7.17.19 + 7.17.20 com.azure azure-identity - 1.18.4 + 1.18.5 compile @@ -503,18 +503,8 @@ - com.hubspot.maven.plugins - prettier-maven-plugin - - - - src/ext/java/**/*.java - src/ext-test/java/**/*.java - src/**/*.json - src/test/resources/org/opentripplanner/apis/**/*.graphql - !src/test/resources/org/opentripplanner/apis/vectortiles/style.json - - + com.diffplug.spotless + spotless-maven-plugin diff --git a/application/src/client/index.html b/application/src/client/index.html index 727bfd9f95f..59e921021f8 100644 --- a/application/src/client/index.html +++ b/application/src/client/index.html @@ -5,8 +5,8 @@ OTP Debug - - + +
diff --git a/application/src/ext-test/java/org/opentripplanner/ext/carpooling/service/DefaultCarpoolingServiceTreeLimitTest.java b/application/src/ext-test/java/org/opentripplanner/ext/carpooling/service/DefaultCarpoolingServiceTreeLimitTest.java index dde031f129e..0ccdf86bedd 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/carpooling/service/DefaultCarpoolingServiceTreeLimitTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/carpooling/service/DefaultCarpoolingServiceTreeLimitTest.java @@ -50,10 +50,10 @@ void sizesEachLegFromItsDurationAndSmallestDownstreamBudget() { stop(Duration.ofMinutes(40)) ); - var limits = DefaultCarpoolingService.driverLegTreeLimits( - trip, - new Duration[] { Duration.ofMinutes(60), Duration.ofMinutes(100) } - ); + var limits = DefaultCarpoolingService.driverLegTreeLimits(trip, new Duration[] { + Duration.ofMinutes(60), + Duration.ofMinutes(100), + }); assertEquals(2, limits.length); // Leg 0 allowance = min(downstream budgets) = min(5, 40) = 5. @@ -78,10 +78,10 @@ void sizesShortLegsWellBelowNearbyStopRadius() { stop(Duration.ofMinutes(2)) ); - var limits = DefaultCarpoolingService.driverLegTreeLimits( - trip, - new Duration[] { Duration.ofMinutes(5), Duration.ofMinutes(5) } - ); + var limits = DefaultCarpoolingService.driverLegTreeLimits(trip, new Duration[] { + Duration.ofMinutes(5), + Duration.ofMinutes(5), + }); var leg = expectedLimit(Duration.ofMinutes(5), Duration.ofMinutes(2)); assertEquals(leg, limits[0]); @@ -96,10 +96,9 @@ void sizesShortLegsWellBelowNearbyStopRadius() { void twoWaypointTripSizesTheSingleLeg() { var trip = trip(stop(BUDGET), stop(BUDGET)); - var limits = DefaultCarpoolingService.driverLegTreeLimits( - trip, - new Duration[] { Duration.ofMinutes(60) } - ); + var limits = DefaultCarpoolingService.driverLegTreeLimits(trip, new Duration[] { + Duration.ofMinutes(60), + }); assertEquals(1, limits.length); assertEquals(expectedLimit(Duration.ofMinutes(60), BUDGET), limits[0]); @@ -112,10 +111,9 @@ void capsEachLegLimitAtMaxTripDuration() { // request could expand a multi-hour street tree. var trip = trip(stop(BUDGET), stop(BUDGET)); - var limits = DefaultCarpoolingService.driverLegTreeLimits( - trip, - new Duration[] { Duration.ofHours(4) } - ); + var limits = DefaultCarpoolingService.driverLegTreeLimits(trip, new Duration[] { + Duration.ofHours(4), + }); assertEquals(CarpoolTrip.MAX_TRIP_DURATION, limits[0]); } diff --git a/application/src/ext-test/java/org/opentripplanner/ext/edgenaming/CrosswalkNamerTest.java b/application/src/ext-test/java/org/opentripplanner/ext/edgenaming/CrosswalkNamerTest.java index eeb66c39a69..055cc752bea 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/edgenaming/CrosswalkNamerTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/edgenaming/CrosswalkNamerTest.java @@ -15,9 +15,9 @@ import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.core.model.i18n.I18NString; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; -import org.opentripplanner.graph_builder.module.osm.OsmDatabase; -import org.opentripplanner.graph_builder.module.osm.StreetEdgePair; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.model.StreetEdgePair; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; import org.opentripplanner.osm.TestOsmProvider; import org.opentripplanner.osm.model.OsmWay; import org.opentripplanner.street.geometry.WgsCoordinate; diff --git a/application/src/ext-test/java/org/opentripplanner/ext/edgenaming/EdgeNamerTest.java b/application/src/ext-test/java/org/opentripplanner/ext/edgenaming/EdgeNamerTest.java index 6e07e9e6716..eaaadc427a2 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/edgenaming/EdgeNamerTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/edgenaming/EdgeNamerTest.java @@ -3,8 +3,8 @@ import static org.junit.jupiter.api.Assertions.assertInstanceOf; import org.junit.jupiter.api.Test; -import org.opentripplanner.graph_builder.services.osm.DefaultNamer; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer.EdgeNamerType; +import org.opentripplanner.graph_builder.module.osm.EdgeNamer.EdgeNamerType; +import org.opentripplanner.graph_builder.module.osm.internal.naming.DefaultNamer; class EdgeNamerTest { diff --git a/application/src/ext-test/java/org/opentripplanner/ext/edgenaming/SidewalkNamerTest.java b/application/src/ext-test/java/org/opentripplanner/ext/edgenaming/SidewalkNamerTest.java index cc44248f8c5..db739aa7fe2 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/edgenaming/SidewalkNamerTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/edgenaming/SidewalkNamerTest.java @@ -11,9 +11,9 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.core.model.i18n.I18NString; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; -import org.opentripplanner.graph_builder.module.osm.OsmDatabase; -import org.opentripplanner.graph_builder.module.osm.StreetEdgePair; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.model.StreetEdgePair; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; import org.opentripplanner.osm.WayTestData; import org.opentripplanner.osm.model.OsmWay; import org.opentripplanner.street.geometry.WgsCoordinate; diff --git a/application/src/ext-test/java/org/opentripplanner/ext/emission/internal/csvdata/route/RouteParserTest.java b/application/src/ext-test/java/org/opentripplanner/ext/emission/internal/csvdata/route/RouteParserTest.java index f1f116f7d97..0ba549bdebe 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/emission/internal/csvdata/route/RouteParserTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/emission/internal/csvdata/route/RouteParserTest.java @@ -11,10 +11,10 @@ class RouteParserTest { private static final String DATA = """ - route_id, avg_co2_per_vehicle_per_km, avg_passenger_count - R:1, 2.0, 20.0 - R:2, 3.0, 24.0 - """; + route_id, avg_co2_per_vehicle_per_km, avg_passenger_count + R:1, 2.0, 20.0 + R:2, 3.0, 24.0 + """; @Test void test() { diff --git a/application/src/ext-test/java/org/opentripplanner/ext/emission/internal/csvdata/trip/TripHopsCsvParserTest.java b/application/src/ext-test/java/org/opentripplanner/ext/emission/internal/csvdata/trip/TripHopsCsvParserTest.java index 078227e308b..7a5e12d7763 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/emission/internal/csvdata/trip/TripHopsCsvParserTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/emission/internal/csvdata/trip/TripHopsCsvParserTest.java @@ -11,10 +11,10 @@ class TripHopsCsvParserTest { private static final String DATA = """ - trip_id, from_stop_id, from_stop_sequence, not_used, co2 - F:1, NSR:Quay:1, 1, xyz, 28.0 - F:1, NSR:Quay:2, 2, abc, 38.0 - """; + trip_id, from_stop_id, from_stop_sequence, not_used, co2 + F:1, NSR:Quay:1, 1, xyz, 28.0 + F:1, NSR:Quay:2, 2, abc, 38.0 + """; @Test void test() { diff --git a/application/src/ext-test/java/org/opentripplanner/ext/emission/internal/itinerary/EmissionItineraryDecoratorTest.java b/application/src/ext-test/java/org/opentripplanner/ext/emission/internal/itinerary/EmissionItineraryDecoratorTest.java index de74dc2adb5..fe7ece6f3cc 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/emission/internal/itinerary/EmissionItineraryDecoratorTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/emission/internal/itinerary/EmissionItineraryDecoratorTest.java @@ -79,16 +79,16 @@ void setUpItineraries() { int t0 = START_TIME; combinedWithFlex = newItinerary(A) - .drive(t0, t0 += 90, C) - .rail(4, t0 += 90, t0 += 90, D) - .bus(routeA, 20, t0, t0 += 90, E) + .drive(t0, (t0 += 90), C) + .rail(4, (t0 += 90), (t0 += 90), D) + .bus(routeA, 20, t0, (t0 += 90), E) .flex(t0 + 90, END_TIME, B) .build(); combinedNoFlex = newItinerary(A) - .drive(t0, t0 += 90, C) - .rail(4, t0 += 90, t0 + 90, D) - .bus(routeA, 20, t0, t0 += 90, E) + .drive(t0, (t0 += 90), C) + .rail(4, (t0 += 90), t0 + 90, D) + .bus(routeA, 20, t0, (t0 += 90), E) .bus(routeB, 23, t0, END_TIME, B) .build(); diff --git a/application/src/ext-test/java/org/opentripplanner/ext/empiricaldelay/internal/csvinput/calendar/CalendarCsvParserTest.java b/application/src/ext-test/java/org/opentripplanner/ext/empiricaldelay/internal/csvinput/calendar/CalendarCsvParserTest.java index 9d655722a3f..b51f6b73530 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/empiricaldelay/internal/csvinput/calendar/CalendarCsvParserTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/empiricaldelay/internal/csvinput/calendar/CalendarCsvParserTest.java @@ -15,9 +15,9 @@ class CalendarCsvParserTest { String.join(", ", CalendarCsvParser.HEADERS) + "\n" + """ - WEEKDAYS,1,1,1,1,1,0,0,2025-01-01, 2025-12-31 - WEEKEND,0,0,0,0,0,1,1,2025-02-03, 2025-11-20 - """; + WEEKDAYS,1,1,1,1,1,0,0,2025-01-01, 2025-12-31 + WEEKEND,0,0,0,0,0,1,1,2025-02-03, 2025-11-20 + """; private final CalendarCsvParser subject = new CalendarCsvParser( DataImportIssueStore.NOOP, CsvReader.parse(DEFAUT_INPUT) diff --git a/application/src/ext-test/java/org/opentripplanner/ext/empiricaldelay/internal/csvinput/delay/TripTimeDelayCsvParserTest.java b/application/src/ext-test/java/org/opentripplanner/ext/empiricaldelay/internal/csvinput/delay/TripTimeDelayCsvParserTest.java index 8c7e99921c2..54d350109af 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/empiricaldelay/internal/csvinput/delay/TripTimeDelayCsvParserTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/empiricaldelay/internal/csvinput/delay/TripTimeDelayCsvParserTest.java @@ -12,10 +12,10 @@ class TripTimeDelayCsvParserTest { private static final String DEFAUT_INPUT = """ - empirical_delay_service_id, trip_id, stop_id, stop_sequence, p50, p90 - WEEKDAYS, VYG:ServiceJourney:BUS-2280_374435-R, NSR:Quay:1, 1, 2, 8 - WEEKEND, RUT:ServiceJourney:bc0092f0102605437e3e49cc3a88d0ba, NSR:Quay:10001, 39, 0, 200 - """; + empirical_delay_service_id, trip_id, stop_id, stop_sequence, p50, p90 + WEEKDAYS, VYG:ServiceJourney:BUS-2280_374435-R, NSR:Quay:1, 1, 2, 8 + WEEKEND, RUT:ServiceJourney:bc0092f0102605437e3e49cc3a88d0ba, NSR:Quay:10001, 39, 0, 200 + """; private static final String FEED_ID = "F"; private final TripTimeDelayCsvParser subject = new TripTimeDelayCsvParser( diff --git a/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v1/custom/AtlantaFareServiceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v1/custom/AtlantaFareServiceTest.java index 8c94a5e716a..28c944e0b2c 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v1/custom/AtlantaFareServiceTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v1/custom/AtlantaFareServiceTest.java @@ -286,8 +286,8 @@ private static Itinerary createItinerary(String agencyId, String shortName, long .withMode(TransitMode.BUS) .build(); - int start = (int) (T11_00 + (startTimeMins * 60)); - int end = (int) (T11_00 + ((startTimeMins + 12) * 60)); + int start = (int) (T11_00 + startTimeMins * 60); + int end = (int) (T11_00 + (startTimeMins + 12) * 60); return newItinerary(Place.forStop(firstStop), start) .bus(route, 1, start, end, Place.forStop(lastStop)) .build(); diff --git a/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v1/custom/HSLFareServiceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v1/custom/HSLFareServiceTest.java index e64a3a9d98e..7d3c6285ff6 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v1/custom/HSLFareServiceTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v1/custom/HSLFareServiceTest.java @@ -114,11 +114,12 @@ private static List createTestCases() { .withTransferDuration(fiveMinutes) .build(); - FareAttribute fareAttributeD = FareAttribute.of(new FeedScopedId(FEED_ID, "D")) - .withPrice(D_PRICE) - .withTransferDuration(fiveMinutes) - //.setAgency(agency1.getId().getId()) - .build(); + FareAttribute fareAttributeD = + FareAttribute.of(new FeedScopedId(FEED_ID, "D")) + .withPrice(D_PRICE) + .withTransferDuration(fiveMinutes) + //.setAgency(agency1.getId().getId()) + .build(); FareAttribute fareAttributeABC = FareAttribute.of(new FeedScopedId(FEED_ID, "ABC")) .withPrice(ABC_PRICE) diff --git a/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v1/custom/OrcaFareServiceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v1/custom/OrcaFareServiceTest.java index 8e97846fdff..bd3c6425b0a 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v1/custom/OrcaFareServiceTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v1/custom/OrcaFareServiceTest.java @@ -180,7 +180,7 @@ private static void assertLegFareEquals(int fare, Leg leg, ItineraryFare fares, // Check for transfer status - transfers are when this leg has fare products but pays no additional cost // (i.e., fare = 0 for this leg because it's covered by a previous fare product) - var hasTransfer = (fare == 0 && !legFareProducts.isEmpty()); + var hasTransfer = fare == 0 && !legFareProducts.isEmpty(); assertEquals(hasXfer, hasTransfer, "Incorrect transfer leg fare product status."); } @@ -834,8 +834,8 @@ private static Itinerary createItinerary( .withGtfsType(transitMode) .build(); - int start = (int) (T11_00 + (startTimeMins * 60)); - int end = (int) (T11_00 + ((startTimeMins + 12) * 60)); + int start = (int) (T11_00 + startTimeMins * 60); + int end = (int) (T11_00 + (startTimeMins + 12) * 60); return newItinerary(Place.forStop(firstStop), start) .transit(route, tripId, start, end, 5, 7, Place.forStop(lastStop), null, null, null) .build(); diff --git a/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v2/FreeTransferInNetworkTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v2/FreeTransferInNetworkTest.java index 8f607033d55..7b3a9eb2c41 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v2/FreeTransferInNetworkTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v2/FreeTransferInNetworkTest.java @@ -73,10 +73,8 @@ void singleLeg() { void severalLegs() { var i1 = newItinerary(A, 0).bus(ROUTE, 1, 0, 50, B).bus(ROUTE, 1, 0, 50, C).build(); var result = service.calculateFares(i1); - i1 - .listTransitLegs() - .forEach(l -> { - assertThat(result.offersForLeg(l)).containsExactly(FareOffer.of(l.startTime(), REGULAR)); - }); + i1.listTransitLegs().forEach(l -> { + assertThat(result.offersForLeg(l)).containsExactly(FareOffer.of(l.startTime(), REGULAR)); + }); } } diff --git a/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v2/WildcardNetworkTransferTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v2/WildcardNetworkTransferTest.java index 83cc4e8e460..e335b7c19a3 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v2/WildcardNetworkTransferTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/service/gtfs/v2/WildcardNetworkTransferTest.java @@ -18,7 +18,9 @@ class WildcardNetworkTransferTest implements FareTestConstants { private final GtfsFaresV2Service SERVICE = GtfsFaresV2Service.of() .withLegRules( // wildcard rule, matches everything - FareLegRule.of(id(1), FARE_PRODUCT_A).withLegGroupId(LEG_GROUP_A).build() + FareLegRule.of(id(1), FARE_PRODUCT_A) + .withLegGroupId(LEG_GROUP_A) + .build() ) .withTransferRules( // monthly pass with unlimited transfers diff --git a/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexIndexTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexIndexTest.java index addda55d3aa..44c196c5a68 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexIndexTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexIndexTest.java @@ -136,11 +136,9 @@ void routesAtGroup() { var groupStop = (GroupStop) st1.getStop(); assertThat(groupStop.getChildLocations()).isNotEmpty(); - groupStop - .getChildLocations() - .forEach(child -> { - assertThat(index.findRoutes(child)).containsExactly(ROUTE_2); - assertThat(index.findRoutes(child)).containsExactly(ROUTE_2); - }); + groupStop.getChildLocations().forEach(child -> { + assertThat(index.findRoutes(child)).containsExactly(ROUTE_2); + assertThat(index.findRoutes(child)).containsExactly(ROUTE_2); + }); } } diff --git a/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTest.java index 2df098e9a12..9cb705147d7 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTest.java @@ -43,8 +43,6 @@ */ public class FlexIntegrationTest { - private static final FlexParameters FLEX_PARAMETERS = FlexParameters.defaultValues(); - public static final GenericLocation OUTSIDE_FLEX_ZONE = GenericLocation.fromCoordinate( 33.7552, -84.4631 @@ -82,14 +80,11 @@ static void setup() { FlexIntegrationTestData.COBB_FLEX_GTFS ) ); - service = TestServerContext.createServerContext( - graph, + var transitService = TestServerContext.createTransitService( transitRepository, - transferRepository, - model.fareServiceFactory().makeFareService(), - null, - FLEX_PARAMETERS - ).routingService(); + transferRepository + ); + service = TestServerContext.createRoutingService(graph, transitService, transferRepository); } @Test diff --git a/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexRouterTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexRouterTest.java index 149be797df1..331e98f69e6 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexRouterTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexRouterTest.java @@ -56,7 +56,9 @@ void runningDateToServiceDateAggregation() { @Test void runningDateToServiceDateAggregationWithFiltering() { var subject = setupEnvironment( - TripRequest.of().withIncludeRoutes(List.of(new FeedScopedId("F", ROUTE1))).build() + TripRequest.of() + .withIncludeRoutes(List.of(new FeedScopedId("F", ROUTE1))) + .build() ); var dates = subject.flexServiceDates(); diff --git a/application/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathTest.java index 46ab8d0c327..3d37de02af4 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathTest.java @@ -13,8 +13,10 @@ class FlexPathTest { private static final int THIRTY_MINS_IN_SECONDS = (int) Duration.ofMinutes(30).toSeconds(); - private static final FlexPath PATH = new FlexPath(10_000, THIRTY_MINS_IN_SECONDS, () -> - LineStrings.SIMPLE + private static final FlexPath PATH = new FlexPath( + 10_000, + THIRTY_MINS_IN_SECONDS, + () -> LineStrings.SIMPLE ); static List cases() { diff --git a/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripIntegrationTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripIntegrationTest.java index ffec571f4a9..83ef8051177 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripIntegrationTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripIntegrationTest.java @@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.test.support.PolylineAssert.assertThatPolylinesAreEqual; +import io.micrometer.core.instrument.Metrics; import java.time.LocalDateTime; import java.time.Month; import java.util.List; @@ -17,7 +18,6 @@ import org.opentripplanner.api.model.geometry.EncodedPolyline; import org.opentripplanner.apis.transmodel.model.TripTimeOnDateHelper; import org.opentripplanner.core.model.id.FeedScopedId; -import org.opentripplanner.ext.fares.service.gtfs.v1.DefaultFareService; import org.opentripplanner.ext.flex.FlexIntegrationTestData; import org.opentripplanner.graph_builder.module.ValidateAndInterpolateStopTimesForEachTrip; import org.opentripplanner.model.GenericLocation; @@ -28,15 +28,17 @@ import org.opentripplanner.routing.algorithm.raptoradapter.router.TransitRouter; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.framework.DebugTimingAggregator; +import org.opentripplanner.routing.linking.VertexLinkerTestFactory; import org.opentripplanner.routing.linking.mapping.LinkingContextRequestMapper; -import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.standalone.api.TestServerContext; +import org.opentripplanner.standalone.config.RouterConfig; import org.opentripplanner.street.graph.Graph; import org.opentripplanner.street.linking.TemporaryVerticesContainer; import org.opentripplanner.transfer.regular.TransferRepository; import org.opentripplanner.transfer.regular.TransferServiceTestFactory; import org.opentripplanner.transit.model.network.grouppriority.TransitGroupPriorityService; import org.opentripplanner.transit.service.TransitRepository; +import org.opentripplanner.transit.service.TransitService; import org.opentripplanner.utils.time.ServiceDateUtils; /** @@ -96,11 +98,9 @@ void parseCobbCountyAsScheduledDeviatedTrip() { void flexTripInTransitMode() { var feedId = transitRepository.getFeedIds().iterator().next(); - var serverContext = TestServerContext.createServerContext( - graph, + var transitService = TestServerContext.createTransitService( transitRepository, - transferRepository, - new DefaultFareService() + transferRepository ); // from zone 3 to zone 2 @@ -113,7 +113,7 @@ void flexTripInTransitMode() { "Zone 1 - PUBLIX Super Market,Zone 1 Collection Point" ); - var itineraries = getItineraries(from, to, serverContext); + var itineraries = getItineraries(from, to, transitService); assertEquals(2, itineraries.size()); @@ -145,11 +145,9 @@ void flexTripInTransitMode() { void intermediateEstimatedCallsSkipFlexWindowStops() { var feedId = transitRepository.getFeedIds().iterator().next(); - var serverContext = TestServerContext.createServerContext( - graph, + var transitService = TestServerContext.createTransitService( transitRepository, - transferRepository, - new DefaultFareService() + transferRepository ); var from = GenericLocation.fromStopId( @@ -161,7 +159,7 @@ void intermediateEstimatedCallsSkipFlexWindowStops() { "Zone 1 - PUBLIX Super Market,Zone 1 Collection Point" ); - var leg = getItineraries(from, to, serverContext).get(0).legs().get(0); + var leg = getItineraries(from, to, transitService).get(0).legs().get(0); // The flexible-area stop is exposed as an intermediate stop on the leg ... var intermediateStopIds = leg @@ -212,7 +210,7 @@ static void setup() { private static List getItineraries( GenericLocation from, GenericLocation to, - OtpServerRequestContext serverContext + TransitService transitService ) { var zoneId = ZoneIds.NEW_YORK; var dateTime = LocalDateTime.of(2021, Month.DECEMBER, 16, 12, 0).atZone(zoneId); @@ -226,24 +224,29 @@ private static List getItineraries( var transitStartOfTime = ServiceDateUtils.asStartOfService(request.dateTime(), zoneId); var additionalSearchDays = AdditionalSearchDays.defaults(dateTime); + var vertexLinker = VertexLinkerTestFactory.of(graph); + var linkingContextFactory = TestServerContext.createLinkingContextFactory( + graph, + vertexLinker, + transitService + ); + try (var temporaryVerticesContainer = new TemporaryVerticesContainer()) { var linkingRequest = LinkingContextRequestMapper.map(request); - var linkingContext = serverContext - .linkingContextFactory() - .create(temporaryVerticesContainer, linkingRequest); + var linkingContext = linkingContextFactory.create(temporaryVerticesContainer, linkingRequest); var result = TransitRouter.route( request, - serverContext.transitService(), - serverContext.graph(), - serverContext.raptorConfig(), - serverContext.meterRegistry(), - serverContext.streetDetailsService(), - serverContext.transferService(), - serverContext.flexParameters(), - serverContext.rideHailingServices(), - serverContext.dataOverlayParameterBindings(), - serverContext.sorlandsbanenService(), - serverContext.viaTransferResolver(), + transitService, + graph, + TestServerContext.createRaptorConfig(), + Metrics.globalRegistry, + TestServerContext.createStreetDetailsService(), + TransferServiceTestFactory.transferService(transferRepository), + RouterConfig.DEFAULT.flexParameters(), + List.of(), + null, + null, + TestServerContext.createViaTransferResolver(graph, transitService), TransitGroupPriorityService.empty(), transitStartOfTime, additionalSearchDays, diff --git a/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/UnscheduledTripTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/UnscheduledTripTest.java index 4ddc998ea49..ea5d079d5fb 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/UnscheduledTripTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/UnscheduledTripTest.java @@ -685,7 +685,7 @@ private static String arrivalToStr(StopTime st) { private static String timeToStr(int time, int start, int end) { return time == MISSING_VALUE - ? (TimeUtils.timeToStrCompact(start) + " - " + TimeUtils.timeToStrCompact(end)) + ? TimeUtils.timeToStrCompact(start) + " - " + TimeUtils.timeToStrCompact(end) : TimeUtils.timeToStrCompact(time); } diff --git a/application/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/application/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 2273e25e497..d9ae14058df 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -126,9 +126,9 @@ static void setup() { transitRepository.index(); var transitService = new DefaultTransitService(transitRepository) { private final Multimap modes = ImmutableMultimap.< - StopLocation, - TransitMode - >builder() + StopLocation, + TransitMode + >builder() .putAll(WESTHAFEN, FERRY, BUS) .build(); diff --git a/application/src/ext-test/java/org/opentripplanner/ext/geocoder/SerializationTest.java b/application/src/ext-test/java/org/opentripplanner/ext/geocoder/SerializationTest.java index bedfd6c7f96..9376c299ced 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/geocoder/SerializationTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/geocoder/SerializationTest.java @@ -12,8 +12,31 @@ class SerializationTest { private static final String STOP_CLUSTER_JSON = """ - { - "primary" : { + { + "primary" : { + "id" : "F:123", + "code" : "aaa", + "type" : "STOP", + "name" : "A stop", + "coordinate" : { + "lat" : 1.0, + "lon" : 2.0 + }, + "modes" : [ + "RAIL" + ], + "agencies" : [ + { + "id" : "F:a1", + "name" : "Agency" + } + ], + "feedPublisher" : { + "name" : "Publisher" + } + }, + "secondaries" : [ + { "id" : "F:123", "code" : "aaa", "type" : "STOP", @@ -34,33 +57,10 @@ class SerializationTest { "feedPublisher" : { "name" : "Publisher" } - }, - "secondaries" : [ - { - "id" : "F:123", - "code" : "aaa", - "type" : "STOP", - "name" : "A stop", - "coordinate" : { - "lat" : 1.0, - "lon" : 2.0 - }, - "modes" : [ - "RAIL" - ], - "agencies" : [ - { - "id" : "F:a1", - "name" : "Agency" - } - ], - "feedPublisher" : { - "name" : "Publisher" - } - } - ] - } - """; + } + ] + } + """; @Test void serialize() { diff --git a/application/src/ext-test/java/org/opentripplanner/ext/ojp/mapping/RouteRequestMapperTest.java b/application/src/ext-test/java/org/opentripplanner/ext/ojp/mapping/RouteRequestMapperTest.java index 73dd4b4828e..0cd5a3a4de0 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/ojp/mapping/RouteRequestMapperTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/ojp/mapping/RouteRequestMapperTest.java @@ -201,9 +201,7 @@ private static List transitFilterCases() { new LineDirectionFilterStructure() .withExclude(false) .withLine( - (new LineDirectionStructure().withLineRef( - new LineRefStructure().withValue("F:route1") - )) + new LineDirectionStructure().withLineRef(new LineRefStructure().withValue("F:route1")) ) ) ), @@ -213,9 +211,9 @@ private static List transitFilterCases() { new LineDirectionFilterStructure() .withExclude(true) .withLine( - (new LineDirectionStructure().withLineRef( - new LineRefStructure().withValue("F:agency1") - )) + new LineDirectionStructure().withLineRef( + new LineRefStructure().withValue("F:agency1") + ) ) ) ), diff --git a/application/src/ext-test/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolverTest.java b/application/src/ext-test/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolverTest.java index 11a10acc4e6..07c2152bc03 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolverTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolverTest.java @@ -180,7 +180,7 @@ private static TransitService makeTransitService( transitRepository.addTripPattern(pattern.getId(), pattern); var serviceCode = pattern.getScheduledTimetable().getTripTimes().getFirst().getServiceCode(); - transitRepository.getServiceCodes().put(pattern.getId(), serviceCode); + transitRepository.putServiceCode(pattern.getId(), serviceCode); calendarServiceData.putServiceDatesForServiceId(pattern.getId(), List.of(serviceDate)); }); diff --git a/application/src/ext-test/java/org/opentripplanner/ext/ridehailing/configure/RideHailingServicesModuleTest.java b/application/src/ext-test/java/org/opentripplanner/ext/ridehailing/configure/RideHailingServicesModuleTest.java index ae6efa685a0..325aa292231 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/ridehailing/configure/RideHailingServicesModuleTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/ridehailing/configure/RideHailingServicesModuleTest.java @@ -15,17 +15,17 @@ class RideHailingServicesModuleTest { void buildServices() throws JsonProcessingException { var module = new RideHailingServicesModule(); var json = """ - { - "rideHailingServices": [ - { - "type": "uber-car-hailing", - "clientId": "secret-id", - "clientSecret": "very-secret", - "wheelchairAccessibleProductId": "product-id-accessible-by-wheelchair" - } - ] - } - """; + { + "rideHailingServices": [ + { + "type": "uber-car-hailing", + "clientId": "secret-id", + "clientSecret": "very-secret", + "wheelchairAccessibleProductId": "product-id-accessible-by-wheelchair" + } + ] + } + """; var jsonNode = ObjectMappers.ignoringExtraFields().readTree(json); var services = module.services(new RouterConfig(jsonNode, json, false)); diff --git a/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesResourceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesResourceTest.java index 290720109b3..d2aa6421561 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesResourceTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesResourceTest.java @@ -5,9 +5,9 @@ import org.glassfish.grizzly.http.server.Request; import org.junit.jupiter.api.Test; import org.mockito.Mockito; -import org.opentripplanner.ext.fares.service.gtfs.v1.DefaultFareService; +import org.opentripplanner.routing.impl.TransitAlertServiceImpl; import org.opentripplanner.standalone.api.TestServerContext; -import org.opentripplanner.street.graph.Graph; +import org.opentripplanner.standalone.config.RouterConfig; import org.opentripplanner.test.support.HttpForTest; import org.opentripplanner.transfer.regular.TransferServiceTestFactory; import org.opentripplanner.transit.service.TransitRepository; @@ -18,19 +18,17 @@ class VectorTilesResourceTest { void tileJson() { // the Grizzly request is awful to instantiate, using Mockito var grizzlyRequest = Mockito.mock(Request.class); - var serverContext = TestServerContext.createServerContext( - new Graph(), + var transitService = TestServerContext.createTransitService( new TransitRepository(), - TransferServiceTestFactory.defaultTransferRepository(), - new DefaultFareService() + TransferServiceTestFactory.defaultTransferRepository() ); var resource = new VectorTilesResource( - serverContext.transitService(), - serverContext.vectorTileConfig(), - serverContext.worldEnvelopeService(), - serverContext.vehicleRentalService(), - serverContext.vehicleParkingService(), - serverContext.transitAlertService(), + transitService, + RouterConfig.DEFAULT.vectorTileConfig(), + TestServerContext.createWorldEnvelopeService(), + TestServerContext.createVehicleRentalService(), + TestServerContext.createVehicleParkingService(), + new TransitAlertServiceImpl(), grizzlyRequest, "default" ); diff --git a/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopsLayerBuilderTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopsLayerBuilderTest.java index bddb5cfb7db..7881ea2f564 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopsLayerBuilderTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopsLayerBuilderTest.java @@ -23,22 +23,22 @@ class AreaStopsLayerBuilderTest { private static final FeedScopedId ID = new FeedScopedId("FEED", "ID"); private static final I18NString NAME = I18NString.of("Test stop"); private static final String CONFIG = """ - { - "vectorTiles": { - "layers" : [ - { - "name": "areaStops", - "type": "AreaStop", - "mapper": "OTPRR", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 60, - "expansionFactor": 0 - } - ] - } + { + "vectorTiles": { + "layers" : [ + { + "name": "areaStops", + "type": "AreaStop", + "mapper": "OTPRR", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 60, + "expansionFactor": 0 + } + ] } - """; + } + """; private static final LayerParameters LAYER_CONFIG = VectorTileConfig.mapVectorTilesParameters(newNodeAdapterForTest(CONFIG), "vectorTiles") .layers() diff --git a/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java index 9f597cc6fbc..b821852c558 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java @@ -89,22 +89,22 @@ public void vehicleParkingGroupGeometryTest() { repository.updateVehicleParking(List.of(vehicleParking), List.of()); var config = """ - { - "vectorTiles": { - "layers" :[ - { - "name": "vehicleParkingGroups", - "type": "VehicleParkingGroup", - "mapper": "Digitransit", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 600, - "expansionFactor": 0 - } - ] - } + { + "vectorTiles": { + "layers" :[ + { + "name": "vehicleParkingGroups", + "type": "VehicleParkingGroup", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 600, + "expansionFactor": 0 + } + ] } - """; + } + """; var nodeAdapter = newNodeAdapterForTest(config); var tiles = VectorTileConfig.mapVectorTilesParameters(nodeAdapter, "vectorTiles"); assertEquals(1, tiles.layers().size()); @@ -159,7 +159,8 @@ public void digitransitVehicleParkingGroupPropertyMapperTranslationTest() { } private static class VehicleParkingGroupsLayerBuilderWithPublicGeometry - extends VehicleParkingGroupsLayerBuilder { + extends VehicleParkingGroupsLayerBuilder + { public VehicleParkingGroupsLayerBuilderWithPublicGeometry( VehicleParkingService service, @@ -176,7 +177,8 @@ public List findGeometries(Envelope query) { } private static class VehicleParkingGroupPropertyMapperWithPublicMap - extends DigitransitVehicleParkingGroupPropertyMapper { + extends DigitransitVehicleParkingGroupPropertyMapper + { public VehicleParkingGroupPropertyMapperWithPublicMap(Locale locale) { super(locale); diff --git a/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerTest.java index 88e1346e2cf..d3b5a28ce16 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerTest.java @@ -84,22 +84,22 @@ public void vehicleParkingGeometryTest() { repo.updateVehicleParking(List.of(vehicleParking), List.of()); var config = """ - { - "vectorTiles": { - "layers" : [ - { - "name": "vehicleParking", - "type": "VehicleParking", - "mapper": "Stadtnavi", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 60, - "expansionFactor": 0 - } - ] - } + { + "vectorTiles": { + "layers" : [ + { + "name": "vehicleParking", + "type": "VehicleParking", + "mapper": "Stadtnavi", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 60, + "expansionFactor": 0 + } + ] } - """; + } + """; var nodeAdapter = newNodeAdapterForTest(config); var tiles = VectorTileConfig.mapVectorTilesParameters(nodeAdapter, "vectorTiles"); assertEquals(1, tiles.layers().size()); diff --git a/application/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java b/application/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java index d90226a753f..aad1959a745 100644 --- a/application/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java +++ b/application/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java @@ -120,7 +120,7 @@ private float compute(StreetLeg leg) { // a score 0.1, everything worse will give you a score of 0! double slopeMalus = (maxSlopeExceeded * maxSlopeExceeded) / 10; - score += (0.5 - slopeMalus); + score += 0.5 - slopeMalus; boolean allEdgesAreAccessible = edges .stream() diff --git a/application/src/ext/java/org/opentripplanner/ext/carpooling/filter/CarpoolingRequestBuilder.java b/application/src/ext/java/org/opentripplanner/ext/carpooling/filter/CarpoolingRequestBuilder.java index ac212bf82a0..bd97a22cadf 100644 --- a/application/src/ext/java/org/opentripplanner/ext/carpooling/filter/CarpoolingRequestBuilder.java +++ b/application/src/ext/java/org/opentripplanner/ext/carpooling/filter/CarpoolingRequestBuilder.java @@ -42,9 +42,8 @@ public CarpoolingRequestBuilder() {} .accessEgress() .maxDuration() .valueOf(StreetMode.WALK); - this.searchWindow = request.searchWindow() == null - ? DEFAULT_SEARCH_WINDOW - : request.searchWindow(); + this.searchWindow = + request.searchWindow() == null ? DEFAULT_SEARCH_WINDOW : request.searchWindow(); } public CarpoolingRequestBuilder withAccessOrEgress(AccessEgressType accessOrEgress) { diff --git a/application/src/ext/java/org/opentripplanner/ext/carpooling/internal/CarpoolItineraryMapper.java b/application/src/ext/java/org/opentripplanner/ext/carpooling/internal/CarpoolItineraryMapper.java index 82db60442da..41a1976736e 100644 --- a/application/src/ext/java/org/opentripplanner/ext/carpooling/internal/CarpoolItineraryMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/carpooling/internal/CarpoolItineraryMapper.java @@ -257,12 +257,10 @@ private static Itinerary buildItinerary( Place pickupPlace = makePlace(pickupVertex); Place dropoffPlace = makePlace(dropoffVertex); - Vertex startBoundaryVertex = walkToPickup != null - ? walkToPickup.states.getFirst().getVertex() - : pickupVertex; - Vertex endBoundaryVertex = walkFromDropoff != null - ? walkFromDropoff.states.getLast().getVertex() - : dropoffVertex; + Vertex startBoundaryVertex = + walkToPickup != null ? walkToPickup.states.getFirst().getVertex() : pickupVertex; + Vertex endBoundaryVertex = + walkFromDropoff != null ? walkFromDropoff.states.getLast().getVertex() : dropoffVertex; Place itineraryStart = boundaryPlace(startLabel, ORIGIN_DEFAULT_NAME, startBoundaryVertex); Place itineraryEnd = boundaryPlace(endLabel, DESTINATION_DEFAULT_NAME, endBoundaryVertex); @@ -349,9 +347,10 @@ static BookingInfo toBookingInfo( if (contact.getPhoneNumber() != null) { bookingMethods.add(BookingMethod.CALL_OFFICE); } - String effectiveUrl = contact.getBookingUrl() == null - ? null - : appendPassengerCoordinates(contact.getBookingUrl(), pickup, dropoff); + String effectiveUrl = + contact.getBookingUrl() == null + ? null + : appendPassengerCoordinates(contact.getBookingUrl(), pickup, dropoff); if (effectiveUrl != null) { bookingMethods.add(BookingMethod.ONLINE); } diff --git a/application/src/ext/java/org/opentripplanner/ext/carpooling/model/CarpoolLeg.java b/application/src/ext/java/org/opentripplanner/ext/carpooling/model/CarpoolLeg.java index 5ca62094bd3..aeddbf24b91 100644 --- a/application/src/ext/java/org/opentripplanner/ext/carpooling/model/CarpoolLeg.java +++ b/application/src/ext/java/org/opentripplanner/ext/carpooling/model/CarpoolLeg.java @@ -22,7 +22,6 @@ import org.opentripplanner.model.plan.walkstep.WalkStep; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.street.model.elevation.ElevationProfile; -import org.opentripplanner.street.model.note.StreetNote; import org.opentripplanner.transfer.constrained.model.ConstrainedTransfer; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.network.Route; @@ -288,11 +287,6 @@ public List listWalkSteps() { return Leg.super.listWalkSteps(); } - @Override - public Set listStreetNotes() { - return Leg.super.listStreetNotes(); - } - @Override public Set listTransitAlerts() { return transitAlerts; diff --git a/application/src/ext/java/org/opentripplanner/ext/carpooling/model/CarpoolTrip.java b/application/src/ext/java/org/opentripplanner/ext/carpooling/model/CarpoolTrip.java index c92e1071407..a670599e7c0 100644 --- a/application/src/ext/java/org/opentripplanner/ext/carpooling/model/CarpoolTrip.java +++ b/application/src/ext/java/org/opentripplanner/ext/carpooling/model/CarpoolTrip.java @@ -55,7 +55,8 @@ */ public class CarpoolTrip extends AbstractTransitEntity - implements LogInfo { + implements LogInfo +{ /** Default total capacity (including driver) when no capacity information is provided. */ public static final int DEFAULT_TOTAL_CAPACITY = 5; diff --git a/application/src/ext/java/org/opentripplanner/ext/carpooling/updater/CarpoolSiriMapper.java b/application/src/ext/java/org/opentripplanner/ext/carpooling/updater/CarpoolSiriMapper.java index 240c009c2c0..9108563ed4c 100644 --- a/application/src/ext/java/org/opentripplanner/ext/carpooling/updater/CarpoolSiriMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/carpooling/updater/CarpoolSiriMapper.java @@ -103,8 +103,8 @@ public CarpoolTrip mapSiriToCarpoolTrip(EstimatedVehicleJourney journey) { for (int i = 0; i < activeCalls.size(); i++) { EstimatedCall call = activeCalls.get(i); - boolean isFirst = (i == 0); - boolean isLast = (i == activeCalls.size() - 1); + boolean isFirst = i == 0; + boolean isLast = i == activeCalls.size() - 1; var stop = buildCarpoolStopForPosition(call, tripId, i, isFirst, isLast); stops.add(stop); @@ -144,9 +144,10 @@ public CarpoolTrip mapSiriToCarpoolTrip(EstimatedVehicleJourney journey) { // trees across the network and degrades every later request. When the destination has no // latest expected arrival, its scheduled arrival plus the default deviation budget is used — // the same default the destination stop itself receives when the feed omits a latest arrival. - var latestArrival = lastStop.getLatestExpectedArrivalTime() != null - ? lastStop.getLatestExpectedArrivalTime() - : endTime.plus(CarpoolStop.DEFAULT_DEVIATION_BUDGET); + var latestArrival = + lastStop.getLatestExpectedArrivalTime() != null + ? lastStop.getLatestExpectedArrivalTime() + : endTime.plus(CarpoolStop.DEFAULT_DEVIATION_BUDGET); var tripDuration = Duration.between(startTime, latestArrival); if (tripDuration.compareTo(CarpoolTrip.MAX_TRIP_DURATION) > 0) { throw new IllegalArgumentException( @@ -347,9 +348,10 @@ private int extractOnboardCount(String tripId, EstimatedCall call) { */ private Duration extractDeviationBudget(EstimatedCall call) { var latestExpected = call.getLatestExpectedArrivalTime(); - var arrivalTime = call.getExpectedArrivalTime() != null - ? call.getExpectedArrivalTime() - : call.getAimedArrivalTime(); + var arrivalTime = + call.getExpectedArrivalTime() != null + ? call.getExpectedArrivalTime() + : call.getAimedArrivalTime(); if (latestExpected == null || arrivalTime == null) { return CarpoolStop.DEFAULT_DEVIATION_BUDGET; @@ -397,9 +399,10 @@ private void validateEstimatedCallOrder(List calls) { // Validate intermediate calls are between first and last for (int i = 1; i < calls.size() - 1; i++) { EstimatedCall intermediateCall = calls.get(i); - ZonedDateTime intermediateTime = intermediateCall.getAimedDepartureTime() != null - ? intermediateCall.getAimedDepartureTime() - : intermediateCall.getAimedArrivalTime(); + ZonedDateTime intermediateTime = + intermediateCall.getAimedDepartureTime() != null + ? intermediateCall.getAimedDepartureTime() + : intermediateCall.getAimedArrivalTime(); if (intermediateTime == null) { LOG.info("Intermediate call at index {} has no timing information", i); @@ -435,9 +438,10 @@ private CarpoolStop toCarpoolStop( var flexibleArea = toFlexibleArea(call); var circleLocation = flexibleArea.getCircularArea(); var legacyGeometry = flexibleArea.getPolygon(); - var centroid = circleLocation == null - ? toWgsCoordinate(toPolygon(legacyGeometry)) - : toWgsCoordinate(circleLocation); + var centroid = + circleLocation == null + ? toWgsCoordinate(toPolygon(legacyGeometry)) + : toWgsCoordinate(circleLocation); return CarpoolStop.of(new FeedScopedId(feedId, id)) .withCoordinate(centroid) diff --git a/application/src/ext/java/org/opentripplanner/ext/carpooling/util/CarReachableVertexSnapper.java b/application/src/ext/java/org/opentripplanner/ext/carpooling/util/CarReachableVertexSnapper.java index f8827383e7d..0b424172885 100644 --- a/application/src/ext/java/org/opentripplanner/ext/carpooling/util/CarReachableVertexSnapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/carpooling/util/CarReachableVertexSnapper.java @@ -265,8 +265,7 @@ private boolean probeEscapes( SphericalDistanceLibrary.fastDistance( originCoordinate, state.getVertex().getCoordinate() - ) >= - minCarEscapeMeters + ) >= minCarEscapeMeters ) { escaped[0] = true; return true; diff --git a/application/src/ext/java/org/opentripplanner/ext/dataoverlay/EdgeUpdaterModule.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/EdgeUpdaterModule.java index f5ff071cf70..8172a675938 100644 --- a/application/src/ext/java/org/opentripplanner/ext/dataoverlay/EdgeUpdaterModule.java +++ b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/EdgeUpdaterModule.java @@ -3,6 +3,8 @@ import org.opentripplanner.ext.dataoverlay.configuration.TimeUnit; import org.opentripplanner.graph_builder.model.GraphBuilderModule; import org.opentripplanner.street.graph.Graph; +import org.opentripplanner.street.model.edge.StreetEdge; +import org.opentripplanner.utils.collection.ListUtils; /** * This class allows updating the graph with the grid data from generic .nc file in accordance with @@ -31,7 +33,7 @@ public void buildGraph() { GenericEdgeUpdater genericEdgeUpdater = new GenericEdgeUpdater( dataFile, timeFormat, - graph.getStreetEdges() + ListUtils.ofIterable(graph.findEdges(StreetEdge.class)) ); genericEdgeUpdater.updateEdges(); } diff --git a/application/src/ext/java/org/opentripplanner/ext/dataoverlay/GenericEdgeUpdater.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/GenericEdgeUpdater.java index 650fe8a70b8..6d63ddd974b 100644 --- a/application/src/ext/java/org/opentripplanner/ext/dataoverlay/GenericEdgeUpdater.java +++ b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/GenericEdgeUpdater.java @@ -133,7 +133,7 @@ private void updateEdge(StreetEdge streetEdge) { edgesUpdated++; - if (LOG.isInfoEnabled() && (edgesUpdated % REPORT_EVERY_N_EDGE) == 0) { + if (LOG.isInfoEnabled() && edgesUpdated % REPORT_EVERY_N_EDGE == 0) { LOG.info(String.format("%d / %d street edges updated", edgesUpdated, streetEdges.size())); } } diff --git a/application/src/ext/java/org/opentripplanner/ext/dataoverlay/routing/DataOverlayContext.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/routing/DataOverlayContext.java index 451f114ec7a..95bff9c1077 100644 --- a/application/src/ext/java/org/opentripplanner/ext/dataoverlay/routing/DataOverlayContext.java +++ b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/routing/DataOverlayContext.java @@ -34,8 +34,6 @@ public DataOverlayContext( /** * Builds the {@link ExtensionRequestContext} list for a request, given the app-singleton * {@link DataOverlayParameterBindings}. - *

- * @return an immutable list. */ public static List listExtensionRequestContexts( DataOverlayParameters dataOverlayRequest, diff --git a/application/src/ext/java/org/opentripplanner/ext/debugrastertiles/DefaultScalarColorPalette.java b/application/src/ext/java/org/opentripplanner/ext/debugrastertiles/DefaultScalarColorPalette.java index 3e6ae85ed10..49cae17c001 100644 --- a/application/src/ext/java/org/opentripplanner/ext/debugrastertiles/DefaultScalarColorPalette.java +++ b/application/src/ext/java/org/opentripplanner/ext/debugrastertiles/DefaultScalarColorPalette.java @@ -9,8 +9,11 @@ * * @author laurent */ -public record DefaultScalarColorPalette(double min, double max, double maxMax) implements - ScalarColorPalette { +public record DefaultScalarColorPalette( + double min, + double max, + double maxMax +) implements ScalarColorPalette { @Override public Color getColor(double value) { if (value > max) { diff --git a/application/src/ext/java/org/opentripplanner/ext/debugrastertiles/EdgeVertexTileRenderer.java b/application/src/ext/java/org/opentripplanner/ext/debugrastertiles/EdgeVertexTileRenderer.java index 9525f168ab3..ca7170d92ce 100644 --- a/application/src/ext/java/org/opentripplanner/ext/debugrastertiles/EdgeVertexTileRenderer.java +++ b/application/src/ext/java/org/opentripplanner/ext/debugrastertiles/EdgeVertexTileRenderer.java @@ -237,8 +237,8 @@ public void renderTile(TileRenderContext context) { } public interface EdgeVertexRenderer { - Comparator DEFAULT_VERTEX_COMPARATOR = Comparator.comparing((Vertex v) -> - v instanceof StreetVertex + Comparator DEFAULT_VERTEX_COMPARATOR = Comparator.comparing( + (Vertex v) -> v instanceof StreetVertex ).reversed(); Comparator DEFAULT_EDGE_COMPARATOR = Comparator.comparing( (Edge e) -> e.getGeometry() != null diff --git a/application/src/ext/java/org/opentripplanner/ext/debugrastertiles/ElevationEdgeRenderer.java b/application/src/ext/java/org/opentripplanner/ext/debugrastertiles/ElevationEdgeRenderer.java index c5c6df822a5..9d81a8e5300 100644 --- a/application/src/ext/java/org/opentripplanner/ext/debugrastertiles/ElevationEdgeRenderer.java +++ b/application/src/ext/java/org/opentripplanner/ext/debugrastertiles/ElevationEdgeRenderer.java @@ -83,11 +83,12 @@ private Double findElevationForVertex(Vertex v) { .getIncomingStreetEdges() .stream() .filter(StreetEdge::hasElevationExtension) - .map(streetEdge -> - streetEdge - .getElevationProfile() - .getCoordinate(streetEdge.getElevationProfile().size() - 1) - .y + .map( + streetEdge -> + streetEdge + .getElevationProfile() + .getCoordinate(streetEdge.getElevationProfile().size() - 1) + .y ), v .getOutgoingStreetEdges() diff --git a/application/src/ext/java/org/opentripplanner/ext/edgenaming/BufferedEdgeProcessor.java b/application/src/ext/java/org/opentripplanner/ext/edgenaming/BufferedEdgeProcessor.java index ee01355d91f..added2477ee 100644 --- a/application/src/ext/java/org/opentripplanner/ext/edgenaming/BufferedEdgeProcessor.java +++ b/application/src/ext/java/org/opentripplanner/ext/edgenaming/BufferedEdgeProcessor.java @@ -37,18 +37,16 @@ public void applyNames(Collection unnamedEdges) { ); final AtomicInteger namesApplied = new AtomicInteger(0); - unnamedEdges - .parallelStream() - .forEach(edgeOnLevel -> { - var buffer = preciseBufferFactory.preciseBuffer(edgeOnLevel.edge().getGeometry()); - if (assigner.assignNameToEdge(edgeOnLevel, buffer)) { - namesApplied.incrementAndGet(); - } + unnamedEdges.parallelStream().forEach(edgeOnLevel -> { + var buffer = preciseBufferFactory.preciseBuffer(edgeOnLevel.edge().getGeometry()); + if (assigner.assignNameToEdge(edgeOnLevel, buffer)) { + namesApplied.incrementAndGet(); + } - // Keep lambda! A method-ref would cause incorrect class and line number to be logged - // noinspection Convert2MethodRef - progress.step(m -> logger.info(m)); - }); + // Keep lambda! A method-ref would cause incorrect class and line number to be logged + // noinspection Convert2MethodRef + progress.step(m -> logger.info(m)); + }); logger.info( "Assigned names to {} of {} {} ({}%)", diff --git a/application/src/ext/java/org/opentripplanner/ext/edgenaming/CrosswalkNamer.java b/application/src/ext/java/org/opentripplanner/ext/edgenaming/CrosswalkNamer.java index fd0c1632c7e..5f505007238 100644 --- a/application/src/ext/java/org/opentripplanner/ext/edgenaming/CrosswalkNamer.java +++ b/application/src/ext/java/org/opentripplanner/ext/edgenaming/CrosswalkNamer.java @@ -10,9 +10,9 @@ import org.locationtech.jts.geom.Geometry; import org.opentripplanner.core.model.i18n.I18NString; import org.opentripplanner.core.model.i18n.LocalizedString; -import org.opentripplanner.graph_builder.module.osm.OsmDatabase; -import org.opentripplanner.graph_builder.module.osm.StreetEdgePair; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.model.StreetEdgePair; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; import org.opentripplanner.osm.model.OsmEntity; import org.opentripplanner.osm.model.OsmWay; import org.slf4j.Logger; diff --git a/application/src/ext/java/org/opentripplanner/ext/edgenaming/EdgeNamerFactory.java b/application/src/ext/java/org/opentripplanner/ext/edgenaming/EdgeNamerFactory.java index ec03c7e8463..5faab907ee3 100644 --- a/application/src/ext/java/org/opentripplanner/ext/edgenaming/EdgeNamerFactory.java +++ b/application/src/ext/java/org/opentripplanner/ext/edgenaming/EdgeNamerFactory.java @@ -1,7 +1,7 @@ package org.opentripplanner.ext.edgenaming; -import org.opentripplanner.graph_builder.services.osm.DefaultNamer; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.internal.naming.DefaultNamer; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; import org.opentripplanner.standalone.config.framework.json.OtpVersion; diff --git a/application/src/ext/java/org/opentripplanner/ext/edgenaming/PortlandCustomNamer.java b/application/src/ext/java/org/opentripplanner/ext/edgenaming/PortlandCustomNamer.java index 7cc9ac5c172..47ea131328f 100644 --- a/application/src/ext/java/org/opentripplanner/ext/edgenaming/PortlandCustomNamer.java +++ b/application/src/ext/java/org/opentripplanner/ext/edgenaming/PortlandCustomNamer.java @@ -3,9 +3,9 @@ import java.util.HashSet; import org.opentripplanner.core.model.i18n.I18NString; import org.opentripplanner.core.model.i18n.NonLocalizedString; -import org.opentripplanner.graph_builder.module.osm.OsmDatabase; -import org.opentripplanner.graph_builder.module.osm.StreetEdgePair; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.model.StreetEdgePair; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; import org.opentripplanner.osm.model.OsmEntity; import org.opentripplanner.osm.model.OsmWay; import org.opentripplanner.street.model.edge.StreetEdge; @@ -75,27 +75,25 @@ public I18NString name(OsmEntity entity) { public void recordEdges(OsmWay way, StreetEdgePair edgePair, OsmDatabase osmdb) { final boolean isHighwayLink = isHighwayLink(way); final boolean isLowerLink = isLowerLink(way); - edgePair - .asIterable() - .forEach(edge -> { - if (!edge.nameIsDerived()) { - // this edge already has a real name so there is nothing to do - return; + edgePair.asIterable().forEach(edge -> { + if (!edge.nameIsDerived()) { + // this edge already has a real name so there is nothing to do + return; + } + if (isHighwayLink) { + if (edge.isBack()) { + nameByDestination.add(edge); + } else { + nameByOrigin.add(edge); } - if (isHighwayLink) { - if (edge.isBack()) { - nameByDestination.add(edge); - } else { - nameByOrigin.add(edge); - } - } else if (isLowerLink) { - if (edge.isBack()) { - nameByOrigin.add(edge); - } else { - nameByDestination.add(edge); - } + } else if (isLowerLink) { + if (edge.isBack()) { + nameByOrigin.add(edge); + } else { + nameByDestination.add(edge); } - }); + } + }); } @Override diff --git a/application/src/ext/java/org/opentripplanner/ext/edgenaming/SidewalkCrosswalkNamer.java b/application/src/ext/java/org/opentripplanner/ext/edgenaming/SidewalkCrosswalkNamer.java index ac970913eac..71e9b45b511 100644 --- a/application/src/ext/java/org/opentripplanner/ext/edgenaming/SidewalkCrosswalkNamer.java +++ b/application/src/ext/java/org/opentripplanner/ext/edgenaming/SidewalkCrosswalkNamer.java @@ -1,9 +1,9 @@ package org.opentripplanner.ext.edgenaming; import org.opentripplanner.core.model.i18n.I18NString; -import org.opentripplanner.graph_builder.module.osm.OsmDatabase; -import org.opentripplanner.graph_builder.module.osm.StreetEdgePair; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.model.StreetEdgePair; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; import org.opentripplanner.osm.model.OsmEntity; import org.opentripplanner.osm.model.OsmWay; diff --git a/application/src/ext/java/org/opentripplanner/ext/edgenaming/SidewalkNamer.java b/application/src/ext/java/org/opentripplanner/ext/edgenaming/SidewalkNamer.java index 1ba9133c014..b85a074201c 100644 --- a/application/src/ext/java/org/opentripplanner/ext/edgenaming/SidewalkNamer.java +++ b/application/src/ext/java/org/opentripplanner/ext/edgenaming/SidewalkNamer.java @@ -14,9 +14,9 @@ import org.locationtech.jts.geom.MultiLineString; import org.locationtech.jts.geom.Point; import org.opentripplanner.core.model.i18n.I18NString; -import org.opentripplanner.graph_builder.module.osm.OsmDatabase; -import org.opentripplanner.graph_builder.module.osm.StreetEdgePair; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.model.StreetEdgePair; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; import org.opentripplanner.osm.model.OsmEntity; import org.opentripplanner.osm.model.OsmLevel; import org.opentripplanner.osm.model.OsmWay; diff --git a/application/src/ext/java/org/opentripplanner/ext/edgenaming/StreetEdgeIndex.java b/application/src/ext/java/org/opentripplanner/ext/edgenaming/StreetEdgeIndex.java index e2ac717ace0..40c5400e9ba 100644 --- a/application/src/ext/java/org/opentripplanner/ext/edgenaming/StreetEdgeIndex.java +++ b/application/src/ext/java/org/opentripplanner/ext/edgenaming/StreetEdgeIndex.java @@ -3,7 +3,7 @@ import java.util.List; import java.util.Set; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.graph_builder.module.osm.StreetEdgePair; +import org.opentripplanner.graph_builder.module.osm.model.StreetEdgePair; import org.opentripplanner.osm.model.OsmLevel; import org.opentripplanner.osm.model.OsmWay; import org.opentripplanner.street.geometry.HashGridSpatialIndex; diff --git a/application/src/ext/java/org/opentripplanner/ext/edgenaming/configure/EdgeNamerModule.java b/application/src/ext/java/org/opentripplanner/ext/edgenaming/configure/EdgeNamerModule.java index 1f8dc518198..4e0eb0edc15 100644 --- a/application/src/ext/java/org/opentripplanner/ext/edgenaming/configure/EdgeNamerModule.java +++ b/application/src/ext/java/org/opentripplanner/ext/edgenaming/configure/EdgeNamerModule.java @@ -4,7 +4,7 @@ import dagger.Provides; import jakarta.inject.Singleton; import org.opentripplanner.ext.edgenaming.EdgeNamerFactory; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.EdgeNamer; import org.opentripplanner.standalone.config.BuildConfig; @Module diff --git a/application/src/ext/java/org/opentripplanner/ext/empiricaldelay/parameters/EmpiricalDelayFeedParameters.java b/application/src/ext/java/org/opentripplanner/ext/empiricaldelay/parameters/EmpiricalDelayFeedParameters.java index dacd142f399..d9e23967691 100644 --- a/application/src/ext/java/org/opentripplanner/ext/empiricaldelay/parameters/EmpiricalDelayFeedParameters.java +++ b/application/src/ext/java/org/opentripplanner/ext/empiricaldelay/parameters/EmpiricalDelayFeedParameters.java @@ -8,8 +8,10 @@ /** * Configuration parameters for a single empirical delay feed data source. */ -public record EmpiricalDelayFeedParameters(String feedId, URI source) implements - DataSourceConfig, Serializable { +public record EmpiricalDelayFeedParameters( + String feedId, + URI source +) implements DataSourceConfig, Serializable { @Override public String toString() { return ToStringBuilder.of(EmpiricalDelayFeedParameters.class) diff --git a/application/src/ext/java/org/opentripplanner/ext/fares/model/FareAttribute.java b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareAttribute.java index 5e19f55d664..7e932add56a 100644 --- a/application/src/ext/java/org/opentripplanner/ext/fares/model/FareAttribute.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareAttribute.java @@ -7,7 +7,8 @@ import org.opentripplanner.transit.model.framework.AbstractTransitEntity; public final class FareAttribute - extends AbstractTransitEntity { + extends AbstractTransitEntity +{ private FeedScopedId agency; private final Money price; diff --git a/application/src/ext/java/org/opentripplanner/ext/fares/model/FareAttributeBuilder.java b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareAttributeBuilder.java index 0f053a93403..ed215b2f447 100644 --- a/application/src/ext/java/org/opentripplanner/ext/fares/model/FareAttributeBuilder.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareAttributeBuilder.java @@ -5,7 +5,8 @@ import org.opentripplanner.transit.model.framework.AbstractEntityBuilder; public class FareAttributeBuilder - extends AbstractEntityBuilder { + extends AbstractEntityBuilder +{ private FeedScopedId agency; private Money price; diff --git a/application/src/ext/java/org/opentripplanner/ext/fares/model/RouteOriginDestination.java b/application/src/ext/java/org/opentripplanner/ext/fares/model/RouteOriginDestination.java index 79f94d1719e..920d751fbba 100644 --- a/application/src/ext/java/org/opentripplanner/ext/fares/model/RouteOriginDestination.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/model/RouteOriginDestination.java @@ -2,5 +2,8 @@ import java.io.Serializable; -public record RouteOriginDestination(String route, String origin, String destination) implements - Serializable {} +public record RouteOriginDestination( + String route, + String origin, + String destination +) implements Serializable {} diff --git a/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/GtfsFaresService.java b/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/GtfsFaresService.java index 87f7204762e..9f0c95e9333 100644 --- a/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/GtfsFaresService.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/GtfsFaresService.java @@ -36,11 +36,9 @@ public ItineraryFare calculateFares(Itinerary itinerary) { * Add a complex set of fare products for a specific leg; */ private static void addLegProducts(Multimap legProducts, ItineraryFare fares) { - legProducts - .entries() - .forEach(e -> { - fares.addFareProduct(e.getKey(), e.getValue()); - }); + legProducts.entries().forEach(e -> { + fares.addFareProduct(e.getKey(), e.getValue()); + }); } public DefaultFareService faresV1() { diff --git a/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v1/custom/HSLFareService.java b/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v1/custom/HSLFareService.java index 395476cdbaf..45703855ec1 100644 --- a/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v1/custom/HSLFareService.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v1/custom/HSLFareService.java @@ -99,8 +99,7 @@ but visit temporarily (maybe 1 stop only) an 'external' zone */ ruleSet .getRouteOriginDestinations() .toString() - .indexOf(routeOriginDestination.toString()) != - -1 + .indexOf(routeOriginDestination.toString()) != -1 ) { isSpecialRoute = true; } @@ -115,7 +114,7 @@ but visit temporarily (maybe 1 stop only) an 'external' zone */ if ( !attribute.isTransferDurationSet() || Duration.between(lastRideStartTime, startTime).getSeconds() < - attribute.getTransferDuration() + attribute.getTransferDuration() ) { Money newFare = attribute.getPrice(); if (newFare.lessThan(bestSpecialFare)) { diff --git a/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v2/FareLookupService.java b/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v2/FareLookupService.java index 5ac524c179a..33d14d9e430 100644 --- a/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v2/FareLookupService.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v2/FareLookupService.java @@ -77,7 +77,8 @@ boolean isEmpty() { * exist. */ Set legRules(TransitLeg leg) { - var rules = this.legRules.stream() + var rules = this.legRules + .stream() .filter(r -> legMatchesRule(leg, r)) .collect(Collectors.toUnmodifiableSet()); var containsPriorities = rules.stream().anyMatch(r -> r.priority().isPresent()); @@ -98,7 +99,8 @@ Set findTransfersMatchingAllLegs( if (legs.size() < 2) { return Set.of(); } - return this.transferRules.stream() + return this.transferRules + .stream() .filter(transferPredicate) .filter(FareTransferRule::isFree) .filter(r -> TimeLimitEvaluator.withinTimeLimit(r, legs.getFirst(), legs.getLast())) @@ -126,7 +128,8 @@ Set findTransferOffersForSubLegs( List tail, Predicate transferPredicate ) { - Set transfers = this.transferRules.stream() + Set transfers = this.transferRules + .stream() .filter(transferPredicate) .flatMap(r -> { var fromRules = findFareLegRule(r.fromLegGroup()); diff --git a/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v2/GtfsFaresV2Service.java b/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v2/GtfsFaresV2Service.java index ac93fe08980..9f9b20625cf 100644 --- a/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v2/GtfsFaresV2Service.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v2/GtfsFaresV2Service.java @@ -58,28 +58,26 @@ public FareResult calculateFares(Itinerary itinerary) { if (transitLegs.size() > 1) { var splits = ListUtils.partitionIntoSplits(transitLegs); splits.forEach(split -> - split - .subTails() - .forEach(tail -> { - var unlimitedTransferOffers = lookup.findTransferOffersForSubLegs( - split.head(), - tail, - FareTransferRule::unlimitedTransfers - ); - tail.forEach(leg -> offerContainer.addToLeg(leg, unlimitedTransferOffers)); - var hasFreeTransfer = lookup.hasFreeTransfers(tail); - if (hasFreeTransfer) { - offerContainer.transferProducts(tail.getFirst(), tail); - } + split.subTails().forEach(tail -> { + var unlimitedTransferOffers = lookup.findTransferOffersForSubLegs( + split.head(), + tail, + FareTransferRule::unlimitedTransfers + ); + tail.forEach(leg -> offerContainer.addToLeg(leg, unlimitedTransferOffers)); + var hasFreeTransfer = lookup.hasFreeTransfers(tail); + if (hasFreeTransfer) { + offerContainer.transferProducts(tail.getFirst(), tail); + } - var transfers = tail.size(); - var limitedTransferOffers = lookup.findTransferOffersForSubLegs( - split.head(), - tail, - t -> t.limitedTransfers() && t.allowsNumberOfTransfers(transfers) - ); - offerContainer.addTransferLimitedOffer(split.head(), tail, limitedTransferOffers); - }) + var transfers = tail.size(); + var limitedTransferOffers = lookup.findTransferOffersForSubLegs( + split.head(), + tail, + t -> t.limitedTransfers() && t.allowsNumberOfTransfers(transfers) + ); + offerContainer.addTransferLimitedOffer(split.head(), tail, limitedTransferOffers); + }) ); } diff --git a/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v2/LegOffer.java b/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v2/LegOffer.java index aef4a360dac..875c1a8243f 100644 --- a/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v2/LegOffer.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v2/LegOffer.java @@ -54,8 +54,11 @@ public FareProduct fareProduct() { /** * A time-limited implementation of the {@link LegOffer} interface that provides fare offer details. */ - record TimeLimitedOffer(FareOffer offer, TimeLimit timeLimit, TransitLeg startLeg) implements - LegOffer { + record TimeLimitedOffer( + FareOffer offer, + TimeLimit timeLimit, + TransitLeg startLeg + ) implements LegOffer { public TimeLimitedOffer { Objects.requireNonNull(timeLimit); } diff --git a/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v2/custom/OregonHopFareFactory.java b/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v2/custom/OregonHopFareFactory.java index ff9a328ffb5..9e248512713 100644 --- a/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v2/custom/OregonHopFareFactory.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/service/gtfs/v2/custom/OregonHopFareFactory.java @@ -458,7 +458,8 @@ public FareService makeFareService() { * @return The fare product from the GTFS, or a generated $0 fare product. */ private Money findFareProduct(FeedScopedId fareProductId) { - Optional potentialRuleMatch = this.fareLegRules.stream() + Optional potentialRuleMatch = this.fareLegRules + .stream() .filter(f -> f .fareProducts() @@ -530,7 +531,7 @@ private Collection generateHopFareProducts( FareProduct.of( ctranId("TRIMET_CTRAN_HC_TRANSFER"), "TriMet to C-TRAN", - Money.max(Money.ZERO_USD, (seniorLarger.minus(seniorSmaller))) + Money.max(Money.ZERO_USD, seniorLarger.minus(seniorSmaller)) ) .withCategory(CATEGORY_HONOURED_CITIZEN) .withMedium(HOP_FASTPASS) diff --git a/application/src/ext/java/org/opentripplanner/ext/flex/AreaStopsToVerticesMapper.java b/application/src/ext/java/org/opentripplanner/ext/flex/AreaStopsToVerticesMapper.java index 78d3b64c48a..94ffafdf714 100644 --- a/application/src/ext/java/org/opentripplanner/ext/flex/AreaStopsToVerticesMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/AreaStopsToVerticesMapper.java @@ -61,17 +61,15 @@ public void buildGraph() { ImmutableMultimap mappedResults = results.collect( ImmutableListMultimap.< - MatchResult, - StreetVertex, - FeedScopedId - >flatteningToImmutableListMultimap(MatchResult::vertex, mr -> Stream.of(mr.stop().getId())) + MatchResult, + StreetVertex, + FeedScopedId + >flatteningToImmutableListMultimap(MatchResult::vertex, mr -> Stream.of(mr.stop().getId())) ); - mappedResults - .keySet() - .forEach(vertex -> { - vertex.addAreaStops(mappedResults.get(vertex)); - }); + mappedResults.keySet().forEach(vertex -> { + vertex.addAreaStops(mappedResults.get(vertex)); + }); LOG.info(progress.completeMessage()); } diff --git a/application/src/ext/java/org/opentripplanner/ext/flex/FlexIndex.java b/application/src/ext/java/org/opentripplanner/ext/flex/FlexIndex.java index 5931ab2ab49..c8d4a7c6e0f 100644 --- a/application/src/ext/java/org/opentripplanner/ext/flex/FlexIndex.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/FlexIndex.java @@ -54,13 +54,11 @@ public FlexIndex(TransitRepository transitRepository) { LocalDate maxDate = serviceDate.plusDays(flexTrip.maxSpanDays()); FlexTripForDate flexTripForDate = new FlexTripForDate(serviceDate, maxDate, flexTrip); - serviceDate - .datesUntil(maxDate.plusDays(1)) - .forEach(runningDate -> { - flexTripsRunningOnDate - .computeIfAbsent(runningDate, d -> new ArrayList<>()) - .add(flexTripForDate); - }); + serviceDate.datesUntil(maxDate.plusDays(1)).forEach(runningDate -> { + flexTripsRunningOnDate + .computeIfAbsent(runningDate, d -> new ArrayList<>()) + .add(flexTripForDate); + }); }); } diff --git a/application/src/ext/java/org/opentripplanner/ext/flex/FlexRouter.java b/application/src/ext/java/org/opentripplanner/ext/flex/FlexRouter.java index 2c5711c9021..ef2f7ac2e0a 100644 --- a/application/src/ext/java/org/opentripplanner/ext/flex/FlexRouter.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/FlexRouter.java @@ -93,7 +93,6 @@ public FlexRouter( this.streetPathToLegsMapper = new StreetPathToLegsMapper( new TransitServiceResolver(transitService), transitService.getTimeZone(), - graph.streetNotesService, streetDetailsService, graph.ellipsoidToGeoidDifference ); diff --git a/application/src/ext/java/org/opentripplanner/ext/flex/filter/FilterMapper.java b/application/src/ext/java/org/opentripplanner/ext/flex/filter/FilterMapper.java index f3c98ecb2aa..68c7e52ba5b 100644 --- a/application/src/ext/java/org/opentripplanner/ext/flex/filter/FilterMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/filter/FilterMapper.java @@ -54,17 +54,13 @@ private TripRequest mapFilters(List filters) { } private void addFilter(TransitFilterRequest sr) { - sr - .not() - .forEach(s -> { - excludedRoutes.addAll(s.routes()); - excludedAgencies.addAll(s.agencies()); - }); - sr - .select() - .forEach(s -> { - selectedRoutes.addAll(s.routes()); - selectedAgencies.addAll(s.agencies()); - }); + sr.not().forEach(s -> { + excludedRoutes.addAll(s.routes()); + excludedAgencies.addAll(s.agencies()); + }); + sr.select().forEach(s -> { + selectedRoutes.addAll(s.routes()); + selectedAgencies.addAll(s.agencies()); + }); } } diff --git a/application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/DirectFlexPathCalculator.java b/application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/DirectFlexPathCalculator.java index 1952cc13832..3b8c256c99a 100644 --- a/application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/DirectFlexPathCalculator.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/DirectFlexPathCalculator.java @@ -29,12 +29,15 @@ public FlexPath calculateFlexPath( int alightStopPosition ) { double distance = SphericalDistanceLibrary.distance(fromv.getCoordinate(), tov.getCoordinate()); - LineString geometry = GeometryUtils.getGeometryFactory().createLineString( - new Coordinate[] { fromv.getCoordinate(), tov.getCoordinate() } - ); - - return new FlexPath((int) distance, (int) (distance / flexSpeed) + DIRECT_EXTRA_TIME, () -> - geometry + LineString geometry = GeometryUtils.getGeometryFactory().createLineString(new Coordinate[] { + fromv.getCoordinate(), + tov.getCoordinate(), + }); + + return new FlexPath( + (int) distance, + (int) (distance / flexSpeed) + DIRECT_EXTRA_TIME, + () -> geometry ); } } diff --git a/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexDirectPathFactory.java b/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexDirectPathFactory.java index 59642b8c25c..b719567b303 100644 --- a/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexDirectPathFactory.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexDirectPathFactory.java @@ -192,8 +192,7 @@ protected boolean isRouteable(FlexAccessTemplate accessTemplate, Vertex flexVert flexVertex, accessTemplate.boardStopPosition, accessTemplate.alightStopPosition - ) != - null + ) != null ); } } diff --git a/application/src/ext/java/org/opentripplanner/ext/flex/trip/FlexTrip.java b/application/src/ext/java/org/opentripplanner/ext/flex/trip/FlexTrip.java index 4cc1e25f561..0bbcaccab3e 100644 --- a/application/src/ext/java/org/opentripplanner/ext/flex/trip/FlexTrip.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/trip/FlexTrip.java @@ -19,8 +19,10 @@ * subclasses encapsulates the different business logic, which the different types of services * adhere to. */ -public abstract class FlexTrip, B extends FlexTripBuilder> - extends AbstractTransitEntity { +public abstract class FlexTrip< + T extends FlexTrip, + B extends FlexTripBuilder +> extends AbstractTransitEntity { public static int STOP_INDEX_NOT_FOUND = -1; diff --git a/application/src/ext/java/org/opentripplanner/ext/flex/trip/FlexTripBuilder.java b/application/src/ext/java/org/opentripplanner/ext/flex/trip/FlexTripBuilder.java index 5990c253f8e..5dd1e447bcb 100644 --- a/application/src/ext/java/org/opentripplanner/ext/flex/trip/FlexTripBuilder.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/trip/FlexTripBuilder.java @@ -4,8 +4,10 @@ import org.opentripplanner.transit.model.framework.AbstractEntityBuilder; import org.opentripplanner.transit.model.timetable.Trip; -public abstract class FlexTripBuilder, B extends FlexTripBuilder> - extends AbstractEntityBuilder { +public abstract class FlexTripBuilder< + T extends FlexTrip, + B extends FlexTripBuilder +> extends AbstractEntityBuilder { private Trip trip; diff --git a/application/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTrip.java b/application/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTrip.java index 5d9cfb7c743..25fef4bc52b 100644 --- a/application/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTrip.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTrip.java @@ -23,7 +23,8 @@ * locations, which are not stops, but other types, such as groups of stops or location areas. */ public class ScheduledDeviatedTrip - extends FlexTrip { + extends FlexTrip +{ private final ScheduledDeviatedStopTime[] stopTimes; diff --git a/application/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripBuilder.java b/application/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripBuilder.java index 062cc111d7e..ce7a4aca14f 100644 --- a/application/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripBuilder.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripBuilder.java @@ -5,7 +5,8 @@ import org.opentripplanner.model.StopTime; public class ScheduledDeviatedTripBuilder - extends FlexTripBuilder { + extends FlexTripBuilder +{ private List stopTimes; diff --git a/application/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTripBuilder.java b/application/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTripBuilder.java index d1c9164a5c5..2a2405afa6d 100644 --- a/application/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTripBuilder.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTripBuilder.java @@ -6,7 +6,8 @@ import org.opentripplanner.routing.api.request.framework.TimePenalty; public class UnscheduledTripBuilder - extends FlexTripBuilder { + extends FlexTripBuilder +{ private List stopTimes; private TimePenalty timePenalty = TimePenalty.NONE; diff --git a/application/src/ext/java/org/opentripplanner/ext/httpresponsetimemetrics/HttpResponseTimeMetricsFilter.java b/application/src/ext/java/org/opentripplanner/ext/httpresponsetimemetrics/HttpResponseTimeMetricsFilter.java index 47fd8cab300..1671d7d73a8 100644 --- a/application/src/ext/java/org/opentripplanner/ext/httpresponsetimemetrics/HttpResponseTimeMetricsFilter.java +++ b/application/src/ext/java/org/opentripplanner/ext/httpresponsetimemetrics/HttpResponseTimeMetricsFilter.java @@ -37,7 +37,8 @@ * to ensure predictable metric cardinality. */ public class HttpResponseTimeMetricsFilter - implements ContainerRequestFilter, ContainerResponseFilter { + implements ContainerRequestFilter, ContainerResponseFilter +{ static final String CLIENT_TAG = "client"; static final String URI_TAG = "uri"; diff --git a/application/src/ext/java/org/opentripplanner/ext/ojp/mapping/StopEventResponseMapper.java b/application/src/ext/java/org/opentripplanner/ext/ojp/mapping/StopEventResponseMapper.java index 70540753d7b..49cb69746d3 100644 --- a/application/src/ext/java/org/opentripplanner/ext/ojp/mapping/StopEventResponseMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/ojp/mapping/StopEventResponseMapper.java @@ -104,8 +104,9 @@ private StopEventResultStructure stopEventResult(CallAtStop call) { } private String eventId(TripTimeOnDate tripTimeOnDate) { - var bytes = (tripTimeOnDate.getStopTimeKey().toString() + - tripTimeOnDate.getServiceDay()).getBytes(StandardCharsets.UTF_8); + var bytes = ( + tripTimeOnDate.getStopTimeKey().toString() + tripTimeOnDate.getServiceDay() + ).getBytes(StandardCharsets.UTF_8); return UUID.nameUUIDFromBytes(bytes).toString(); } diff --git a/application/src/ext/java/org/opentripplanner/ext/ojp/mapping/TripResponseContextMapper.java b/application/src/ext/java/org/opentripplanner/ext/ojp/mapping/TripResponseContextMapper.java index fb24ce7d1ab..b201deed857 100644 --- a/application/src/ext/java/org/opentripplanner/ext/ojp/mapping/TripResponseContextMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/ojp/mapping/TripResponseContextMapper.java @@ -74,8 +74,8 @@ private static Stream stopLocations(Itinerary itinerary) { private static Stream stopLocations(Leg leg) { var fromTo = Stream.of(leg.from().stop, leg.to().stop); - var intermediate = StreamUtils.ofNullableCollection(leg.listIntermediateStops()).map(sa -> - sa.place.stop + var intermediate = StreamUtils.ofNullableCollection(leg.listIntermediateStops()).map( + sa -> sa.place.stop ); return Stream.concat(fromTo, intermediate); } diff --git a/application/src/ext/java/org/opentripplanner/ext/ojp/mapping/TripResponseMapper.java b/application/src/ext/java/org/opentripplanner/ext/ojp/mapping/TripResponseMapper.java index f8a4e80a8a7..c940a94f264 100644 --- a/application/src/ext/java/org/opentripplanner/ext/ojp/mapping/TripResponseMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/ojp/mapping/TripResponseMapper.java @@ -84,17 +84,15 @@ public OJP mapTripPlan(RoutingResponse otpResponse, ZonedDateTime timestamp) { } private TripResultStructure mapItinerary(Itinerary itinerary) { - return new TripResultStructure() - .withId(tripId(itinerary)) - .withTrip( - new TripStructure() - .withId(tripId(itinerary)) - .withDuration(Duration.between(itinerary.startTime(), itinerary.endTime())) - .withTransfers(itinerary.legs().size() - 1) - .withStartTime(new XmlDateTime(itinerary.startTime())) - .withEndTime(new XmlDateTime(itinerary.endTime())) - .withLeg(mapLegs(itinerary)) - ); + return new TripResultStructure().withId(tripId(itinerary)).withTrip( + new TripStructure() + .withId(tripId(itinerary)) + .withDuration(Duration.between(itinerary.startTime(), itinerary.endTime())) + .withTransfers(itinerary.legs().size() - 1) + .withStartTime(new XmlDateTime(itinerary.startTime())) + .withEndTime(new XmlDateTime(itinerary.endTime())) + .withLeg(mapLegs(itinerary)) + ); } private List mapLegs(Itinerary itinerary) { diff --git a/application/src/ext/java/org/opentripplanner/ext/ojp/resource/OjpResource.java b/application/src/ext/java/org/opentripplanner/ext/ojp/resource/OjpResource.java index ca5bd4bb581..65da9e73ab0 100644 --- a/application/src/ext/java/org/opentripplanner/ext/ojp/resource/OjpResource.java +++ b/application/src/ext/java/org/opentripplanner/ext/ojp/resource/OjpResource.java @@ -33,18 +33,18 @@ public class OjpResource { private static final Logger LOG = LoggerFactory.getLogger(OjpResource.class); private static final String EXPLORER_HTML = """ - - - - - - OJP Explorer - - - -

- - """; + + + + + + OJP Explorer + + + +
+ + """; private final RequestHandler handler; private final RouteRequest defaultRouteRequest; diff --git a/application/src/ext/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolver.java b/application/src/ext/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolver.java index 7dfb19ac07f..3e819c27c86 100644 --- a/application/src/ext/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolver.java +++ b/application/src/ext/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolver.java @@ -48,7 +48,7 @@ private Leg mapLeg(Leg leg) { } // Only ScheduledTransitLeg has leg references atm, so this check is just to be future-proof - if (!(leg.isScheduledTransitLeg())) { + if (!leg.isScheduledTransitLeg()) { return leg; } var realTimeLeg = ref.getLeg(transitService, transitAlertService); diff --git a/application/src/ext/java/org/opentripplanner/ext/reportapi/model/GraphReportBuilder.java b/application/src/ext/java/org/opentripplanner/ext/reportapi/model/GraphReportBuilder.java index 8b7aeb0f72f..a523456f909 100644 --- a/application/src/ext/java/org/opentripplanner/ext/reportapi/model/GraphReportBuilder.java +++ b/application/src/ext/java/org/opentripplanner/ext/reportapi/model/GraphReportBuilder.java @@ -1,6 +1,5 @@ package org.opentripplanner.ext.reportapi.model; -import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.function.Function; @@ -32,7 +31,7 @@ public static GraphStats build(TransitService transitService, Graph graph) { GraphReportBuilder::firstLetterToLowerCase ); - var edgeTypes = countValues(graph.getEdges(), GraphReportBuilder::firstLetterToLowerCase); + var edgeTypes = countValues(graph.listEdges(), GraphReportBuilder::firstLetterToLowerCase); var vertexTypes = countValues(graph.getVertices(), GraphReportBuilder::firstLetterToLowerCase); return new GraphStats( @@ -52,15 +51,16 @@ private static String firstLetterToLowerCase(Object instance) { return Character.toLowerCase(className.charAt(0)) + className.substring(1); } - private static TypeStats countValues(Collection input, Function classify) { + private static TypeStats countValues(Iterable input, Function classify) { Map result = new HashMap<>(); - input.forEach(item -> { + int total = 0; + for (T item : input) { var classification = classify.apply(item); var count = result.getOrDefault(classification, 0); result.put(classification, ++count); - }); - - return new TypeStats(input.size(), result); + ++total; + } + return new TypeStats(total, result); } public record GraphStats(StreetStats street, TransitStats transit) {} diff --git a/application/src/ext/java/org/opentripplanner/ext/reportapi/model/TransfersReport.java b/application/src/ext/java/org/opentripplanner/ext/reportapi/model/TransfersReport.java index 0be2e903f92..a886ebf4401 100644 --- a/application/src/ext/java/org/opentripplanner/ext/reportapi/model/TransfersReport.java +++ b/application/src/ext/java/org/opentripplanner/ext/reportapi/model/TransfersReport.java @@ -76,18 +76,18 @@ String export() { transfers.forEach(t -> { var from = pointInfo(t.getFrom(), ALIGHT); var to = pointInfo(t.getTo(), BOARD); - var dist = (from.coordinate == null || to.coordinate == null) - ? "" - : String.format( - "%.0fm", - SphericalDistanceLibrary.fastDistance( - from.coordinate.asJtsCoordinate(), - to.coordinate.asJtsCoordinate() - ) - ); - var duration = (from.time == NOT_SET || to.time == NOT_SET) - ? "" - : durationToStr(to.time - from.time); + var dist = + from.coordinate == null || to.coordinate == null + ? "" + : String.format( + "%.0fm", + SphericalDistanceLibrary.fastDistance( + from.coordinate.asJtsCoordinate(), + to.coordinate.asJtsCoordinate() + ) + ); + var duration = + from.time == NOT_SET || to.time == NOT_SET ? "" : durationToStr(to.time - from.time); var c = t.getTransferConstraint(); buf.addText(t.getId() == null ? "" : t.getId().getId()); diff --git a/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdaterParameters.java b/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdaterParameters.java index 54fa43d4e4b..e3c2bea508d 100644 --- a/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdaterParameters.java +++ b/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdaterParameters.java @@ -11,7 +11,8 @@ public class SiriAzureETUpdaterParameters extends SiriAzureUpdaterParameters - implements UrlUpdaterParameters { + implements UrlUpdaterParameters +{ private LocalDate fromDateTime; diff --git a/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureUpdater.java b/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureUpdater.java index 4c1ab5450f2..a428a97a222 100644 --- a/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureUpdater.java +++ b/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureUpdater.java @@ -188,17 +188,14 @@ public void run() { updaterType + ":ServiceBusSubscription" ); - executeStartupStep( - () -> { - var initialData = fetchInitialSiriData(); - if (initialData.isEmpty()) { - LOG.info("Got empty response from history endpoint"); - } else { - processInitialSiriData(initialData.get()); - } - }, - updaterType + ":HistoricalSiriData" - ); + executeStartupStep(() -> { + var initialData = fetchInitialSiriData(); + if (initialData.isEmpty()) { + LOG.info("Got empty response from history endpoint"); + } else { + processInitialSiriData(initialData.get()); + } + }, updaterType + ":HistoricalSiriData"); if (isSuccess) { executeStartupStep(this::startEventProcessor, updaterType + ":ServiceBusEventProcessor"); @@ -427,7 +424,7 @@ private Optional fetchInitialSiriData() { response -> SiriXml.parseXml(response.body()) ); var t2 = System.currentTimeMillis(); - LOG.info("Fetched initial data in {} ms", (t2 - t1)); + LOG.info("Fetched initial data in {} ms", t2 - t1); if (siriOptional.isEmpty()) { LOG.info("Got status 204 'No Content'."); @@ -444,7 +441,7 @@ public void processInitialSiriData(ServiceDelivery serviceDelivery) { if (f != null) { f.get(); } - LOG.info("{} updater initialized in {} ms.", updaterType, (System.currentTimeMillis() - t1)); + LOG.info("{} updater initialized in {} ms.", updaterType, System.currentTimeMillis() - t1); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new SiriAzureInitializationException("Interrupted while applying history", e); @@ -477,8 +474,7 @@ private void errorConsumer(ServiceBusErrorContext errorContext) { if ( reason == ServiceBusFailureReason.MESSAGING_ENTITY_DISABLED || // should this be recoverable? - reason == - ServiceBusFailureReason.MESSAGING_ENTITY_NOT_FOUND + reason == ServiceBusFailureReason.MESSAGING_ENTITY_NOT_FOUND ) { LOG.error( "An unrecoverable error occurred. Stopping processing with reason {} {}", diff --git a/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/MergePaths.java b/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/MergePaths.java index ae01478fef6..8ca78acdce6 100644 --- a/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/MergePaths.java +++ b/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/MergePaths.java @@ -15,9 +15,8 @@ * Everything from the main result is kept, and any additional rail results from the alternative * search are added. */ -class MergePaths - implements - BiFunction>, Collection>, Collection>> { +class MergePaths implements + BiFunction>, Collection>, Collection>> { @Override public Collection> apply( diff --git a/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java index f19a6cd3a4b..e97c7d5da18 100644 --- a/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java +++ b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java @@ -103,6 +103,6 @@ private static boolean isShortWalkLeg(Leg leg) { * for the from/to stops. */ private boolean needsToRenameStops(ScheduledTransitLeg stl) { - return (service.isSecondaryStop(stl.from().stop) || service.isPrimaryStop(stl.to().stop)); + return service.isSecondaryStop(stl.from().stop) || service.isPrimaryStop(stl.to().stop); } } diff --git a/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationParser.java b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationParser.java index 782233a8b05..2adddd62128 100644 --- a/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationParser.java +++ b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationParser.java @@ -38,10 +38,10 @@ public static List parseGroups(InputStream is) { .stream() .collect( ImmutableListMultimap.< - StopGroupEntry, - String, - StopGroupEntry - >flatteningToImmutableListMultimap(x -> x.groupId, Stream::of) + StopGroupEntry, + String, + StopGroupEntry + >flatteningToImmutableListMultimap(x -> x.groupId, Stream::of) ); return groups diff --git a/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationRepository.java b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationRepository.java index 4c9552b9a1e..c771ab4c128 100644 --- a/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationRepository.java +++ b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationRepository.java @@ -11,7 +11,8 @@ @Singleton public class DefaultStopConsolidationRepository - implements Serializable, StopConsolidationRepository { + implements Serializable, StopConsolidationRepository +{ private final List groups = new ArrayList<>(); diff --git a/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopLegBuilder.java b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopLegBuilder.java index b2c42a5410b..f3e7123af89 100644 --- a/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopLegBuilder.java +++ b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopLegBuilder.java @@ -6,7 +6,8 @@ import org.opentripplanner.transit.model.site.StopLocation; public class ConsolidatedStopLegBuilder - extends ScheduledTransitLegBuilder { + extends ScheduledTransitLegBuilder +{ private Place from; private Place to; diff --git a/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopPropertyMapper.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopPropertyMapper.java index fa5d2f6648f..7aa99cccab7 100644 --- a/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopPropertyMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopPropertyMapper.java @@ -33,15 +33,16 @@ protected static AreaStopPropertyMapper create(TransitService transitService, Lo @Override protected Collection map(AreaStop stop) { - var routeColors = getRoutesForStop - .apply(stop) - .stream() - .map(Route::getColor) - .filter(Objects::nonNull) - .distinct() - // the MVT spec explicitly doesn't cover how to encode arrays - // https://docs.mapbox.com/data/tilesets/guides/vector-tiles-standards/#what-the-spec-doesnt-cover - .collect(Collectors.joining(",")); + var routeColors = + getRoutesForStop + .apply(stop) + .stream() + .map(Route::getColor) + .filter(Objects::nonNull) + .distinct() + // the MVT spec explicitly doesn't cover how to encode arrays + // https://docs.mapbox.com/data/tilesets/guides/vector-tiles-standards/#what-the-spec-doesnt-cover + .collect(Collectors.joining(",")); return List.of( new KeyValue("gtfsId", stop.getId().toString()), new KeyValue("name", i18NStringMapper.mapNonnullToApi(stop.getName())), diff --git a/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java index 567729b140f..93835c4bad0 100644 --- a/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java @@ -11,7 +11,8 @@ import org.opentripplanner.inspector.vector.KeyValue; public class DigitransitVehicleParkingGroupPropertyMapper - extends PropertyMapper { + extends PropertyMapper +{ private static final ObjectMapper OBJECT_MAPPER = ObjectMappers.ignoringExtraFields(); private final I18NStringMapper i18NStringMapper; diff --git a/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalStationsLayerBuilder.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalStationsLayerBuilder.java index 53ecb64f248..4ec725475c5 100644 --- a/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalStationsLayerBuilder.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalStationsLayerBuilder.java @@ -13,7 +13,8 @@ import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; public class VehicleRentalStationsLayerBuilder - extends VehicleRentalLayerBuilder { + extends VehicleRentalLayerBuilder +{ public VehicleRentalStationsLayerBuilder( VehicleRentalService service, diff --git a/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalVehiclesLayerBuilder.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalVehiclesLayerBuilder.java index d3520a993ed..c86d71b58c8 100644 --- a/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalVehiclesLayerBuilder.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalVehiclesLayerBuilder.java @@ -11,7 +11,8 @@ import org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle; public class VehicleRentalVehiclesLayerBuilder - extends VehicleRentalLayerBuilder { + extends VehicleRentalLayerBuilder +{ public VehicleRentalVehiclesLayerBuilder( VehicleRentalService service, diff --git a/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java index 89f466bd73e..d513797122f 100644 --- a/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java @@ -13,7 +13,8 @@ import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; public class DigitransitRealtimeVehicleRentalStationPropertyMapper - extends PropertyMapper { + extends PropertyMapper +{ private final I18NStringMapper i18NStringMapper; diff --git a/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java index 8fd712880b6..be4d13d2927 100644 --- a/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java @@ -12,7 +12,8 @@ import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; public class DigitransitVehicleRentalStationPropertyMapper - extends PropertyMapper { + extends PropertyMapper +{ private final I18NStringMapper i18NStringMapper; diff --git a/application/src/ext/java/org/opentripplanner/ext/vehicleparking/liipi/LiipiHubToVehicleParkingGroupMapper.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/liipi/LiipiHubToVehicleParkingGroupMapper.java index cd59110fb16..86fdc8af4ee 100644 --- a/application/src/ext/java/org/opentripplanner/ext/vehicleparking/liipi/LiipiHubToVehicleParkingGroupMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/liipi/LiipiHubToVehicleParkingGroupMapper.java @@ -42,14 +42,12 @@ public Map parseHub(JsonNode jsonNode) { try { Map translations = new HashMap<>(); JsonNode nameNode = jsonNode.path("name"); - nameNode - .fieldNames() - .forEachRemaining(lang -> { - String name = nameNode.path(lang).asText(); - if (!name.isEmpty()) { - translations.put(lang, nameNode.path(lang).asText()); - } - }); + nameNode.fieldNames().forEachRemaining(lang -> { + String name = nameNode.path(lang).asText(); + if (!name.isEmpty()) { + translations.put(lang, nameNode.path(lang).asText()); + } + }); I18NString name = translations.isEmpty() ? new NonLocalizedString(hubId.getId()) : TranslatedString.getI18NString(translations, false); diff --git a/application/src/ext/java/org/opentripplanner/ext/vehicleparking/liipi/LiipiParkToVehicleParkingMapper.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/liipi/LiipiParkToVehicleParkingMapper.java index 739e5a75d0a..e818e4b58a0 100644 --- a/application/src/ext/java/org/opentripplanner/ext/vehicleparking/liipi/LiipiParkToVehicleParkingMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/liipi/LiipiParkToVehicleParkingMapper.java @@ -80,14 +80,12 @@ public VehicleParking parsePark( ); Map translations = new HashMap<>(); JsonNode nameNode = jsonNode.path("name"); - nameNode - .fieldNames() - .forEachRemaining(lang -> { - String name = nameNode.path(lang).asText(); - if (!name.isEmpty()) { - translations.put(lang, nameNode.path(lang).asText()); - } - }); + nameNode.fieldNames().forEachRemaining(lang -> { + String name = nameNode.path(lang).asText(); + if (!name.isEmpty()) { + translations.put(lang, nameNode.path(lang).asText()); + } + }); I18NString name = translations.isEmpty() ? new NonLocalizedString(vehicleParkId.getId()) : TranslatedString.getI18NString(translations, false); diff --git a/application/src/main/java/com/jhlabs/awt/TextStroke.java b/application/src/main/java/com/jhlabs/awt/TextStroke.java index 14c7a688ac8..a02bd3e33c5 100644 --- a/application/src/main/java/com/jhlabs/awt/TextStroke.java +++ b/application/src/main/java/com/jhlabs/awt/TextStroke.java @@ -102,9 +102,10 @@ public Shape createStrokedShape(Shape shape) { float x = lastX + next * dx * r; float y = lastY + next * dy * r; float advance = nextAdvance; - nextAdvance = currentChar < length - 1 - ? glyphVector.getGlyphMetrics(currentChar + 1).getAdvance() * 0.5f - : 0; + nextAdvance = + currentChar < length - 1 + ? glyphVector.getGlyphMetrics(currentChar + 1).getAdvance() * 0.5f + : 0; t.setToTranslation(x, y); t.rotate(angle); t.translate(-px - advance, -py + (height * factor) / 2.0f); diff --git a/application/src/main/java/org/opentripplanner/api/model/serverinfo/OtpBadgeGenerator.java b/application/src/main/java/org/opentripplanner/api/model/serverinfo/OtpBadgeGenerator.java index 0a1426cee85..0b2125f9df4 100644 --- a/application/src/main/java/org/opentripplanner/api/model/serverinfo/OtpBadgeGenerator.java +++ b/application/src/main/java/org/opentripplanner/api/model/serverinfo/OtpBadgeGenerator.java @@ -32,27 +32,27 @@ public class OtpBadgeGenerator { private static final int TEXT_INSET = 5; private static final int FONT_WIDTH = 82; private static final String TEMPLATE = """ - - {{label}}: {{body}} - - - - - - - - - - - - - """; + + {{label}}: {{body}} + + + + + + + + + + + + + """; /** * A color is valid if it is a: @@ -73,7 +73,7 @@ public static boolean isValidColor(String color) { * label it should. */ public static boolean isValidLabel(String label) { - return (label.length() <= 120 && LABEL_PATTERN.matcher(label).matches()); + return label.length() <= 120 && LABEL_PATTERN.matcher(label).matches(); } /** diff --git a/application/src/main/java/org/opentripplanner/api/resource/UpdaterStatusResource.java b/application/src/main/java/org/opentripplanner/api/resource/UpdaterStatusResource.java index 193e689c0ed..53c33bb1ea6 100644 --- a/application/src/main/java/org/opentripplanner/api/resource/UpdaterStatusResource.java +++ b/application/src/main/java/org/opentripplanner/api/resource/UpdaterStatusResource.java @@ -7,7 +7,7 @@ import jakarta.ws.rs.core.Context; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; -import org.opentripplanner.standalone.api.OtpServerRequestContext; +import org.opentripplanner.transit.service.TransitService; import org.opentripplanner.updater.GraphUpdaterStatus; /** @@ -18,23 +18,23 @@ @Produces(MediaType.APPLICATION_JSON) public class UpdaterStatusResource { - private final OtpServerRequestContext serverContext; + private final TransitService transitService; public UpdaterStatusResource( - @Context OtpServerRequestContext serverContext, + @Context TransitService transitService, /** * @deprecated The support for multiple routers are removed from OTP2. * See https://github.com/opentripplanner/OpenTripPlanner/issues/2760 */ @Deprecated @PathParam("ignoreRouterId") String ignoreRouterId ) { - this.serverContext = serverContext; + this.transitService = transitService; } /** Return a list of all agencies in the graph. */ @GET public Response getUpdaters() { - GraphUpdaterStatus updaterStatus = serverContext.transitService().getUpdaterStatus(); + GraphUpdaterStatus updaterStatus = transitService.getUpdaterStatus(); if (updaterStatus == null) { return Response.status(Response.Status.NOT_FOUND).entity("No updaters running.").build(); } @@ -47,7 +47,7 @@ public Response getUpdaters() { @GET @Path("/{updaterId}") public Response getUpdaters(@PathParam("updaterId") int updaterId) { - GraphUpdaterStatus updaterStatus = serverContext.transitService().getUpdaterStatus(); + GraphUpdaterStatus updaterStatus = transitService.getUpdaterStatus(); if (updaterStatus == null) { return Response.status(Response.Status.NOT_FOUND).entity("No updaters running.").build(); } diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/DefaultValueInjector.java b/application/src/main/java/org/opentripplanner/apis/gtfs/DefaultValueInjector.java index 975ac23303a..eeca0959ff2 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/DefaultValueInjector.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/DefaultValueInjector.java @@ -408,36 +408,37 @@ private static ObjectValue mapVehicleOptimize( TimeSlopeSafetyTriangle triangle, Function typeMapper ) { - var optimizationField = type == VehicleRoutingOptimizeType.TRIANGLE - ? ObjectField.newObjectField() - .name("triangle") - .value( - ObjectValue.newObjectValue() - .objectField( - ObjectField.newObjectField() - .name("flatness") - .value(FloatValue.of(triangle.slope())) - .build() - ) - .objectField( - ObjectField.newObjectField() - .name("safety") - .value(FloatValue.of(triangle.safety())) - .build() - ) - .objectField( - ObjectField.newObjectField() - .name("time") - .value(FloatValue.of(triangle.time())) - .build() - ) - .build() - ) - .build() - : ObjectField.newObjectField() - .name("type") - .value(EnumValue.of(typeMapper.apply(type).name())) - .build(); + var optimizationField = + type == VehicleRoutingOptimizeType.TRIANGLE + ? ObjectField.newObjectField() + .name("triangle") + .value( + ObjectValue.newObjectValue() + .objectField( + ObjectField.newObjectField() + .name("flatness") + .value(FloatValue.of(triangle.slope())) + .build() + ) + .objectField( + ObjectField.newObjectField() + .name("safety") + .value(FloatValue.of(triangle.safety())) + .build() + ) + .objectField( + ObjectField.newObjectField() + .name("time") + .value(FloatValue.of(triangle.time())) + .build() + ) + .build() + ) + .build() + : ObjectField.newObjectField() + .name("type") + .value(EnumValue.of(typeMapper.apply(type).name())) + .build(); return ObjectValue.newObjectValue().objectField(optimizationField).build(); } @@ -460,25 +461,26 @@ private static ObjectField mapVehicleParkingSelects( ) { var selects = selectList .stream() - .map(select -> - (Value) ObjectValue.newObjectValue() - .objectField( - ObjectField.newObjectField() - .name("tags") - .value( - ArrayValue.newArrayValue() - .values( - select - .tags() - .stream() - .map(tag -> (Value) StringValue.of(tag)) - .toList() - ) - .build() - ) - .build() - ) - .build() + .map( + select -> + (Value) ObjectValue.newObjectValue() + .objectField( + ObjectField.newObjectField() + .name("tags") + .value( + ArrayValue.newArrayValue() + .values( + select + .tags() + .stream() + .map(tag -> (Value) StringValue.of(tag)) + .toList() + ) + .build() + ) + .build() + ) + .build() ) .toList(); return ObjectField.newObjectField() @@ -523,10 +525,10 @@ public DefaultMappingBuilder enumListReq(String key, List valueList) { key, ArrayValue.newArrayValue() .values( - (valueList - .stream() - .map(value -> (Value) new EnumValue(value.name())) - .toList()) + valueList + .stream() + .map(value -> (Value) new EnumValue(value.name())) + .toList() ) .build() ); diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java b/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java index 508d5037107..0ed2d08f8cb 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java @@ -19,7 +19,6 @@ import java.util.Map; import org.opentripplanner.apis.support.TracingUtils; import org.opentripplanner.routing.api.request.RouteRequest; -import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,7 +63,7 @@ public Response getGraphQL( @HeaderParam("OTPMaxResolves") @DefaultValue("1000000") int maxResolves, @Context HttpHeaders headers, @Context UriInfo uriInfo, - @Context OtpServerRequestContext serverContext + @Context GtfsGraphQLRequestContext requestContext ) { if (jsonParameters == null || !jsonParameters.containsKey("query")) { LOG.debug("No query found in body"); @@ -74,9 +73,10 @@ public Response getGraphQL( .build(); } - Locale locale = headers.getAcceptableLanguages().size() > 0 - ? headers.getAcceptableLanguages().get(0) - : defaultRouteRequest.preferences().locale(); + Locale locale = + headers.getAcceptableLanguages().size() > 0 + ? headers.getAcceptableLanguages().get(0) + : defaultRouteRequest.preferences().locale(); String query = (String) jsonParameters.get("query"); Object queryVariables = jsonParameters.getOrDefault("variables", null); @@ -104,7 +104,7 @@ public Response getGraphQL( maxResolves, timeout, locale, - GraphQLRequestContext.ofServerContext(serverContext), + requestContext, TracingUtils.findTagsInHeadersOrQueryParameters( gtfsApiParameters.tracingTags(), headers, @@ -121,11 +121,12 @@ public Response getGraphQL( @HeaderParam("OTPMaxResolves") @DefaultValue("1000000") int maxResolves, @Context HttpHeaders headers, @Context UriInfo uriInfo, - @Context OtpServerRequestContext serverContext + @Context GtfsGraphQLRequestContext requestContext ) { - Locale locale = headers.getAcceptableLanguages().size() > 0 - ? headers.getAcceptableLanguages().get(0) - : defaultRouteRequest.preferences().locale(); + Locale locale = + headers.getAcceptableLanguages().size() > 0 + ? headers.getAcceptableLanguages().get(0) + : defaultRouteRequest.preferences().locale(); return GtfsGraphQLIndex.getGraphQLResponse( query, null, @@ -133,7 +134,7 @@ public Response getGraphQL( maxResolves, timeout, locale, - GraphQLRequestContext.ofServerContext(serverContext), + requestContext, TracingUtils.findTagsInHeadersOrQueryParameters( gtfsApiParameters.tracingTags(), headers, diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java b/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java index 542e8ccc768..a6070338466 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java @@ -33,7 +33,7 @@ static ExecutionResult getGraphQLExecutionResult( int maxResolves, int timeoutMs, Locale locale, - GraphQLRequestContext requestContext, + GtfsGraphQLRequestContext requestContext, Iterable tracingTags ) { Instrumentation instrumentation = new MaxQueryComplexityInstrumentation(maxResolves); @@ -84,7 +84,7 @@ static Response getGraphQLResponse( int maxResolves, int timeoutMs, Locale locale, - GraphQLRequestContext requestContext, + GtfsGraphQLRequestContext requestContext, Iterable tracingTags ) { ExecutionResult executionResult = getGraphQLExecutionResult( diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/GraphQLRequestContext.java b/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLRequestContext.java similarity index 69% rename from application/src/main/java/org/opentripplanner/apis/gtfs/GraphQLRequestContext.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLRequestContext.java index 8e0a0fb390a..de7d194d421 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/GraphQLRequestContext.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLRequestContext.java @@ -10,11 +10,10 @@ import org.opentripplanner.service.realtimevehicles.RealtimeVehicleService; import org.opentripplanner.service.vehicleparking.VehicleParkingService; import org.opentripplanner.service.vehiclerental.VehicleRentalService; -import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.transfer.regular.RegularTransferService; import org.opentripplanner.transit.service.TransitService; -public record GraphQLRequestContext( +public record GtfsGraphQLRequestContext( RoutingService routingService, TransitService transitService, TransitAlertService transitAlertService, @@ -28,23 +27,6 @@ public record GraphQLRequestContext( NearbyStopFinder nearbyStopFinder, RouteRequest defaultRouteRequest ) { - public static GraphQLRequestContext ofServerContext(OtpServerRequestContext context) { - return new GraphQLRequestContext( - context.routingService(), - context.transitService(), - context.transitAlertService(), - context.transferService(), - context.fareService(), - context.vehicleRentalService(), - context.vehicleParkingService(), - context.realtimeVehicleService(), - context.gtfsSchema(), - context.nearbyPlaceFinder(), - context.nearbyStopFinder(), - context.defaultRouteRequest() - ); - } - /** * Returns a clone of the default route request. The clone is necessary because one HTTP * request can lead to several GraphQL queries, for example through batch or alias queries. diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/IntrospectionTypeWiring.java b/application/src/main/java/org/opentripplanner/apis/gtfs/IntrospectionTypeWiring.java index 289279ac422..b25f6caaee6 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/IntrospectionTypeWiring.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/IntrospectionTypeWiring.java @@ -18,11 +18,9 @@ class IntrospectionTypeWiring { private static final Predicate IS_METHOD_PUBLIC = method -> Modifier.isPublic(method.getModifiers()); - private static final Predicate IS_METHOD_RETURN_TYPE_DATA_FETCHER = ((Predicate< - Method - >) method -> method.getReturnType().equals(DataFetcher.class)).or(method -> - Arrays.asList(method.getReturnType().getInterfaces()).contains(DataFetcher.class) - ); + private static final Predicate IS_METHOD_RETURN_TYPE_DATA_FETCHER = ( + (Predicate) method -> method.getReturnType().equals(DataFetcher.class) + ).or(method -> Arrays.asList(method.getReturnType().getInterfaces()).contains(DataFetcher.class)); private final TypeDefinitionRegistry typeRegistry; diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AgencyImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AgencyImpl.java index ce527fa3250..410c92b02b5 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AgencyImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AgencyImpl.java @@ -7,7 +7,7 @@ import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.routing.alertpatch.EntitySelector; @@ -115,11 +115,11 @@ private List getRoutes(DataFetchingEnvironment environment) { } private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } private TransitAlertService getTransitAlertService(DataFetchingEnvironment environment) { - return environment.getContext().transitAlertService(); + return environment.getContext().transitAlertService(); } private Agency getSource(DataFetchingEnvironment environment) { diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AlertImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AlertImpl.java index b585ecde6f3..592dd299685 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AlertImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AlertImpl.java @@ -14,12 +14,13 @@ import java.util.Objects; import java.util.stream.Collectors; import javax.annotation.Nullable; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLAlertEffectType; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLAlertSeverityLevelType; import org.opentripplanner.apis.gtfs.mapping.AlertCauseMapper; +import org.opentripplanner.apis.gtfs.model.OffsetDateTimeRange; import org.opentripplanner.apis.gtfs.model.RouteTypeModel; import org.opentripplanner.apis.gtfs.model.StopOnRouteModel; import org.opentripplanner.apis.gtfs.model.StopOnTripModel; @@ -44,6 +45,20 @@ public class AlertImpl implements GraphQLDataFetchers.GraphQLAlert { private static final String FALLBACK_EMPTY_STRING = ""; + @Override + public DataFetcher> activityPeriods() { + return environment -> { + var zoneId = getTransitService(environment).getTimeZone(); + return getSource(environment) + .calendar() + .timePeriods() + .stream() + .map(period -> OffsetDateTimeRange.of(period, zoneId)) + .sorted(OffsetDateTimeRange.CHRONOLOGICAL_ORDER) + .toList(); + }; + } + @Override public DataFetcher agency() { return environment -> @@ -400,7 +415,7 @@ private Object getUnknownForAlertEntityPair( } private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } private TransitAlert getSource(DataFetchingEnvironment environment) { diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/DepartureRowImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/DepartureRowImpl.java index d39f401de6d..3d8df57a527 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/DepartureRowImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/DepartureRowImpl.java @@ -4,8 +4,8 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; import java.time.Duration; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.GraphQLUtils; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.model.TripTimeOnDate; @@ -58,7 +58,7 @@ public DataFetcher> stoptimes() { } private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } private PatternAtStop getSource(DataFetchingEnvironment environment) { diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java index e5d6aad924a..1368e6f3e69 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java @@ -6,7 +6,7 @@ import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.model.FeedPublisher; @@ -93,11 +93,11 @@ private List getAgencies(DataFetchingEnvironment environment) { } private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } private TransitAlertService getTransitAlertService(DataFetchingEnvironment environment) { - return environment.getContext().transitAlertService(); + return environment.getContext().transitAlertService(); } private String getSource(DataFetchingEnvironment environment) { diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java index 4d989c30d8e..647a1cb0c0e 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java @@ -9,7 +9,7 @@ import java.util.stream.Collectors; import org.dataloader.DataLoader; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.mapping.LocalDateMapper; @@ -124,23 +124,21 @@ public DataFetcher> fareProducts() { return List.of(); } Leg leg = getSource(environment); - return loader - .load(itinerary) - .thenApply(fare -> { - if (fare == null || fare.isEmpty()) { - return List.of(); - } - var legOffers = new ArrayList<>(fare.getLegProducts().get(leg)); - // Itinerary-level products (e.g. day passes) only apply to transit legs - var itineraryOffers = leg.isTransitLeg() - ? fare - .getItineraryProducts() - .stream() - .map(fp -> FareOffer.of(itinerary.legs().getFirst().startTime(), fp)) - .toList() - : List.of(); - return (Iterable) ListUtils.combine(itineraryOffers, legOffers); - }); + return loader.load(itinerary).thenApply(fare -> { + if (fare == null || fare.isEmpty()) { + return List.of(); + } + var legOffers = new ArrayList<>(fare.getLegProducts().get(leg)); + // Itinerary-level products (e.g. day passes) only apply to transit legs + var itineraryOffers = leg.isTransitLeg() + ? fare + .getItineraryProducts() + .stream() + .map(fp -> FareOffer.of(itinerary.legs().getFirst().startTime(), fp)) + .toList() + : List.of(); + return (Iterable) ListUtils.combine(itineraryOffers, legOffers); + }); }; return (DataFetcher>) fetcher; } @@ -376,24 +374,24 @@ private DataFetcher> alternativeLegs(NavigationDirection direction boolean limitToExactOriginStop = originModesWithParentStation == null || - !(originModesWithParentStation - .stream() - .map(GraphQLTypes.GraphQLTransitMode::toString) - .toList() - .contains(originalLeg.mode().name())); + !originModesWithParentStation + .stream() + .map(GraphQLTypes.GraphQLTransitMode::toString) + .toList() + .contains(originalLeg.mode().name()); boolean limitToExactDestinationStop = destinationModesWithParentStation == null || - !(destinationModesWithParentStation - .stream() - .map(GraphQLTypes.GraphQLTransitMode::toString) - .toList() - .contains(originalLeg.mode().name())); + !destinationModesWithParentStation + .stream() + .map(GraphQLTypes.GraphQLTransitMode::toString) + .toList() + .contains(originalLeg.mode().name()); var res = AlternativeLegs.getAlternativeLegs( environment.getSource(), numberOfLegs, - environment.getContext().transitService(), + environment.getContext().transitService(), direction, AlternativeLegsFilter.NO_FILTER, limitToExactOriginStop, @@ -430,6 +428,6 @@ private Leg getSource(DataFetchingEnvironment environment) { } private TransitService transitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } } diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java index 7b7c982155d..dfe2ffa5f0f 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java @@ -13,12 +13,13 @@ import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.LineString; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLPatternTripsOnServiceDateArgs; import org.opentripplanner.apis.gtfs.service.ApiTransitService; import org.opentripplanner.apis.gtfs.support.time.LocalDateRangeUtil; +import org.opentripplanner.apis.gtfs.support.time.OffsetDateTimeRangeUtil; import org.opentripplanner.apis.support.SemanticHash; import org.opentripplanner.framework.graphql.GraphQLUtils; import org.opentripplanner.routing.alertpatch.EntitySelector; @@ -89,9 +90,10 @@ public DataFetcher> alerts() { alert .entities() .stream() - .anyMatch(entity -> - (entity instanceof EntitySelector.StopAndRoute stopAndRoute && - stopAndRoute.routeId().equals(getRoute(environment).getId())) + .anyMatch( + entity -> + entity instanceof EntitySelector.StopAndRoute stopAndRoute && + stopAndRoute.routeId().equals(getRoute(environment).getId()) ) ) .toList() @@ -115,9 +117,10 @@ public DataFetcher> alerts() { alert .entities() .stream() - .anyMatch(entity -> - (entity instanceof EntitySelector.StopAndTrip stopAndTrip && - stopAndTrip.tripId().equals(getSource(environment).getId())) + .anyMatch( + entity -> + entity instanceof EntitySelector.StopAndTrip stopAndTrip && + stopAndTrip.tripId().equals(getSource(environment).getId()) ) ) .toList() @@ -260,6 +263,10 @@ public DataFetcher> canceledTrips() { var args = new GraphQLTypes.GraphQLPatternCanceledTripsArgs(environment.getArguments()); var serviceDateRanges = LocalDateRangeUtil.mapRanges(args.getGraphQLServiceDateRanges()); + var runningTimePeriods = OffsetDateTimeRangeUtil.mapRanges( + args.getGraphQLRunningTimeRanges(), + "runningTimeRanges" + ); var requestBuilder = TripOnServiceDateRequest.of().withIncludePatterns( FilterValues.ofEmptyIsEverything("patterns", List.of(pattern.getId())) @@ -269,6 +276,11 @@ public DataFetcher> canceledTrips() { FilterValues.ofRequired("serviceDateRanges", serviceDateRanges) ); } + if (runningTimePeriods != null) { + requestBuilder.withIncludeRunningTimePeriods( + FilterValues.ofRequired("runningTimeRanges", runningTimePeriods) + ); + } return transitService.findCanceledTrips(requestBuilder.build()); }; @@ -291,15 +303,15 @@ private List getTrips(DataFetchingEnvironment environment) { } private RealtimeVehicleService getRealtimeVehiclesService(DataFetchingEnvironment environment) { - return environment.getContext().realTimeVehicleService(); + return environment.getContext().realTimeVehicleService(); } private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } private TransitAlertService getTransitAlertService(DataFetchingEnvironment environment) { - return environment.getContext().transitAlertService(); + return environment.getContext().transitAlertService(); } private TripPattern getSource(DataFetchingEnvironment environment) { diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanConnectionImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanConnectionImpl.java index 5886f487d24..6381d28f094 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanConnectionImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanConnectionImpl.java @@ -7,7 +7,7 @@ import graphql.schema.DataFetchingEnvironment; import java.time.Duration; import java.time.OffsetDateTime; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.model.PlanPageInfo; import org.opentripplanner.model.plan.Itinerary; @@ -44,16 +44,18 @@ public DataFetcher> routingErrors() { @Override public DataFetcher pageInfo() { return environment -> { - var startCursor = getSource(environment).getNextPageCursor() != null - ? getSource(environment).getPreviousPageCursor().encode() - : null; + var startCursor = + getSource(environment).getNextPageCursor() != null + ? getSource(environment).getPreviousPageCursor().encode() + : null; ConnectionCursor startConnectionCursor = null; if (startCursor != null) { startConnectionCursor = new DefaultConnectionCursor(startCursor); } - var endCursor = getSource(environment).getPreviousPageCursor() != null - ? getSource(environment).getNextPageCursor().encode() - : null; + var endCursor = + getSource(environment).getPreviousPageCursor() != null + ? getSource(environment).getNextPageCursor().encode() + : null; ConnectionCursor endConnectionCursor = null; if (endCursor != null) { endConnectionCursor = new DefaultConnectionCursor(endCursor); @@ -74,7 +76,7 @@ public DataFetcher pageInfo() { } private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } private RoutingResponse getSource(DataFetchingEnvironment environment) { diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java index 6127c6b8219..86a8efb2599 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java @@ -1,8 +1,6 @@ package org.opentripplanner.apis.gtfs.datafetchers; -import static org.opentripplanner.apis.gtfs.mapping.AlertCauseMapper.getGraphQLCause; -import static org.opentripplanner.apis.gtfs.mapping.AlertEffectMapper.getGraphQLEffect; -import static org.opentripplanner.apis.gtfs.mapping.SeverityMapper.getGraphQLSeverity; +import static org.opentripplanner.apis.gtfs.support.filter.AlertsFilter.filterAlerts; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimaps; @@ -27,16 +25,18 @@ import javax.annotation.Nullable; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Envelope; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.GraphQLUtils; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLQueryTypeStopsByRadiusArgs; +import org.opentripplanner.apis.gtfs.mapping.AlertsConnectionFilterMapper; import org.opentripplanner.apis.gtfs.mapping.CanceledTripsFilterMapper; import org.opentripplanner.apis.gtfs.mapping.routerequest.LegacyRouteRequestMapper; import org.opentripplanner.apis.gtfs.mapping.routerequest.RouteRequestMapper; import org.opentripplanner.apis.gtfs.model.CanceledTripsSummary; import org.opentripplanner.apis.gtfs.support.filter.PatternByDateFilterUtil; +import org.opentripplanner.apis.gtfs.support.sort.AlertsConnectionOrdering; import org.opentripplanner.apis.gtfs.support.time.LocalDateRangeUtil; import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.ext.fares.model.FareRuleSet; @@ -56,7 +56,6 @@ import org.opentripplanner.place.api.PatternAtStop; import org.opentripplanner.place.api.PlaceAtDistance; import org.opentripplanner.place.api.PlaceType; -import org.opentripplanner.routing.alertpatch.EntitySelector; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.response.RoutingResponse; @@ -117,13 +116,25 @@ public DataFetcher> alerts() { }; } + @Override + public DataFetcher> alertsConnection() { + return environment -> { + var args = new GraphQLTypes.GraphQLQueryTypeAlertsConnectionArgs(environment.getArguments()); + var request = AlertsConnectionFilterMapper.map(args.getGraphQLFilters()); + var alerts = getTransitAlertService(environment).findAlerts(request); + return new SimpleCountedListConnection<>(AlertsConnectionOrdering.sort(alerts)).get( + environment + ); + }; + } + @Override public DataFetcher bikePark() { return environment -> { var args = new GraphQLTypes.GraphQLQueryTypeBikeParkArgs(environment.getArguments()); VehicleParkingService vehicleParkingService = environment - .getContext() + .getContext() .vehicleParkingService(); return vehicleParkingService @@ -139,7 +150,7 @@ public DataFetcher bikePark() { public DataFetcher> bikeParks() { return environment -> { VehicleParkingService vehicleParkingService = environment - .getContext() + .getContext() .vehicleParkingService(); return vehicleParkingService.listBikeParks().stream().toList(); @@ -152,7 +163,7 @@ public DataFetcher bikeRentalStation() { var args = new GraphQLTypes.GraphQLQueryTypeBikeRentalStationArgs(environment.getArguments()); VehicleRentalService vehicleRentalStationService = environment - .getContext() + .getContext() .vehicleRentalService(); return vehicleRentalStationService @@ -170,7 +181,7 @@ public DataFetcher bikeRentalStation() { public DataFetcher> bikeRentalStations() { return environment -> { VehicleRentalService vehicleRentalStationService = environment - .getContext() + .getContext() .vehicleRentalService(); var args = new GraphQLTypes.GraphQLQueryTypeBikeRentalStationsArgs( @@ -215,7 +226,7 @@ public DataFetcher carPark() { var args = new GraphQLTypes.GraphQLQueryTypeCarParkArgs(environment.getArguments()); VehicleParkingService vehicleParkingService = environment - .getContext() + .getContext() .vehicleParkingService(); return vehicleParkingService @@ -231,7 +242,7 @@ public DataFetcher carPark() { public DataFetcher> carParks() { return environment -> { VehicleParkingService vehicleParkingService = environment - .getContext() + .getContext() .vehicleParkingService(); var args = new GraphQLTypes.GraphQLQueryTypeCarParksArgs(environment.getArguments()); @@ -310,35 +321,40 @@ public DataFetcher> nearest() { GraphQLTypes.GraphQLInputFiltersInput filterByIds = args.getGraphQLFilterByIds(); if (filterByIds != null) { - filterByStops = filterByIds.getGraphQLStops() != null - ? FeedScopedId.parse(filterByIds.getGraphQLStops()) - : null; - filterByStations = filterByIds.getGraphQLStations() != null - ? FeedScopedId.parse(filterByIds.getGraphQLStations()) - : null; - filterByRoutes = filterByIds.getGraphQLRoutes() != null - ? FeedScopedId.parse(filterByIds.getGraphQLRoutes()) - : null; + filterByStops = + filterByIds.getGraphQLStops() != null + ? FeedScopedId.parse(filterByIds.getGraphQLStops()) + : null; + filterByStations = + filterByIds.getGraphQLStations() != null + ? FeedScopedId.parse(filterByIds.getGraphQLStations()) + : null; + filterByRoutes = + filterByIds.getGraphQLRoutes() != null + ? FeedScopedId.parse(filterByIds.getGraphQLRoutes()) + : null; filterByBikeRentalStations = filterByIds.getGraphQLBikeRentalStations(); } - List filterByModes = args.getGraphQLFilterByModes() != null - ? args - .getGraphQLFilterByModes() - .stream() - .map(mode -> { - try { - return TransitMode.valueOf(mode.name()); - } catch (IllegalArgumentException ignored) { - return null; - } - }) - .filter(Objects::nonNull) - .toList() - : null; - List filterByPlaceTypes = args.getGraphQLFilterByPlaceTypes() != null - ? args.getGraphQLFilterByPlaceTypes().stream().map(GraphQLUtils::toModel).toList() - : DEFAULT_PLACE_TYPES; + List filterByModes = + args.getGraphQLFilterByModes() != null + ? args + .getGraphQLFilterByModes() + .stream() + .map(mode -> { + try { + return TransitMode.valueOf(mode.name()); + } catch (IllegalArgumentException ignored) { + return null; + } + }) + .filter(Objects::nonNull) + .toList() + : null; + List filterByPlaceTypes = + args.getGraphQLFilterByPlaceTypes() != null + ? args.getGraphQLFilterByPlaceTypes().stream().map(GraphQLUtils::toModel).toList() + : DEFAULT_PLACE_TYPES; List filterByNetwork = args.getGraphQLFilterByNetwork(); List places; @@ -387,7 +403,7 @@ public DataFetcher node() { var args = new GraphQLTypes.GraphQLQueryTypeNodeArgs(environment.getArguments()); String type = args.getGraphQLId().getType(); String id = args.getGraphQLId().getId(); - final GraphQLRequestContext context = environment.getContext(); + final GtfsGraphQLRequestContext context = environment.getContext(); TransitService transitService = context.transitService(); VehicleParkingService vehicleParkingService = context.vehicleParkingService(); VehicleRentalService vehicleRentalStationService = context.vehicleRentalService(); @@ -518,7 +534,7 @@ public DataFetcher> patternsByIds() { @Override public DataFetcher> plan() { return environment -> { - GraphQLRequestContext context = environment.getContext(); + GtfsGraphQLRequestContext context = environment.getContext(); RouteRequest request = LegacyRouteRequestMapper.toRouteRequest(environment, context); return getPlanResult(context, request); }; @@ -527,7 +543,7 @@ public DataFetcher> plan() { @Override public DataFetcher> planConnection() { return environment -> { - GraphQLRequestContext context = environment.getContext(); + GtfsGraphQLRequestContext context = environment.getContext(); RouteRequest request = RouteRequestMapper.toRouteRequest(environment, context); return getPlanResult(context, request); }; @@ -539,7 +555,7 @@ public DataFetcher rentalVehicle() { var args = new GraphQLTypes.GraphQLQueryTypeRentalVehicleArgs(environment.getArguments()); VehicleRentalService vehicleRentalStationService = environment - .getContext() + .getContext() .vehicleRentalService(); return vehicleRentalStationService @@ -557,7 +573,7 @@ public DataFetcher rentalVehicle() { public DataFetcher> rentalVehicles() { return environment -> { VehicleRentalService vehicleRentalStationService = environment - .getContext() + .getContext() .vehicleRentalService(); var args = new GraphQLTypes.GraphQLQueryTypeRentalVehiclesArgs(environment.getArguments()); @@ -794,9 +810,10 @@ public DataFetcher> stopsByRadius() { public DataFetcher> ticketTypes() { return environment -> { var fareService = getFareService(environment); - Map> fareRules = fareService instanceof GtfsFaresService - ? ((GtfsFaresService) fareService).faresV1().getFareRulesPerType() - : ((DefaultFareService) fareService).getFareRulesPerType(); + Map> fareRules = + fareService instanceof GtfsFaresService + ? ((GtfsFaresService) fareService).faresV1().getFareRulesPerType() + : ((DefaultFareService) fareService).getFareRulesPerType(); return fareRules .entrySet() @@ -869,7 +886,7 @@ public DataFetcher vehicleParking() { var args = new GraphQLTypes.GraphQLQueryTypeVehicleParkingArgs(environment.getArguments()); VehicleParkingService vehicleParkingService = environment - .getContext() + .getContext() .vehicleParkingService(); var vehicleParkingId = FeedScopedId.parseStrict(args.getGraphQLId()); @@ -886,7 +903,7 @@ public DataFetcher vehicleParking() { public DataFetcher> vehicleParkings() { return environment -> { VehicleParkingService vehicleParkingService = environment - .getContext() + .getContext() .vehicleParkingService(); var args = new GraphQLTypes.GraphQLQueryTypeVehicleParkingsArgs(environment.getArguments()); @@ -916,7 +933,7 @@ public DataFetcher vehicleRentalStation() { ); VehicleRentalService vehicleRentalStationService = environment - .getContext() + .getContext() .vehicleRentalService(); var id = args.getGraphQLId(); @@ -935,7 +952,7 @@ public DataFetcher vehicleRentalStation() { public DataFetcher> vehicleRentalStations() { return environment -> { VehicleRentalService vehicleRentalStationService = environment - .getContext() + .getContext() .vehicleRentalService(); var args = new GraphQLTypes.GraphQLQueryTypeVehicleRentalStationsArgs( @@ -969,7 +986,7 @@ public DataFetcher> vehicleRentalStations() { public DataFetcher> vehicleRentalsByBbox() { return environment -> { VehicleRentalService vehicleRentalService = environment - .getContext() + .getContext() .vehicleRentalService(); var args = new GraphQLTypes.GraphQLQueryTypeVehicleRentalsByBboxArgs( @@ -997,26 +1014,26 @@ private boolean stationIdMatches(VehicleRentalStation station, String feedScoped } private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } private TransitAlertService getTransitAlertService(DataFetchingEnvironment environment) { - return environment.getContext().transitAlertService(); + return environment.getContext().transitAlertService(); } private FareService getFareService(DataFetchingEnvironment environment) { - return environment.getContext().fareService(); + return environment.getContext().fareService(); } private NearbyPlaceFinder getNearbyPlaceFinder(DataFetchingEnvironment environment) { - return environment.getContext().nearbyPlaceFinder(); + return environment.getContext().nearbyPlaceFinder(); } private NearbyStopFinder getNearbyStopFinder(DataFetchingEnvironment environment) { - return environment.getContext().nearbyStopFinder(); + return environment.getContext().nearbyStopFinder(); } - private DataFetcherResult getPlanResult(GraphQLRequestContext context, RouteRequest request) { + private DataFetcherResult getPlanResult(GtfsGraphQLRequestContext context, RouteRequest request) { RoutingResponse res = context.routingService().route(request); res.getDebugTimingAggregator().finishedRendering(); return DataFetcherResult.newResult() @@ -1025,48 +1042,6 @@ private DataFetcherResult getPlanResult(GraphQLRequestContext context, RouteRequ .build(); } - protected static List filterAlerts( - Collection alerts, - GraphQLTypes.GraphQLQueryTypeAlertsArgs args - ) { - var severities = args.getGraphQLSeverityLevel(); - var effects = args.getGraphQLEffect(); - var causes = args.getGraphQLCause(); - return alerts - .stream() - .filter( - alert -> - args.getGraphQLFeeds() == null || - args.getGraphQLFeeds().contains(alert.getId().getFeedId()) - ) - .filter( - alert -> severities == null || severities.contains(getGraphQLSeverity(alert.severity())) - ) - .filter(alert -> effects == null || effects.contains(getGraphQLEffect(alert.effect()))) - .filter(alert -> causes == null || causes.contains(getGraphQLCause(alert.cause()))) - .filter( - alert -> - args.getGraphQLRoute() == null || - alert - .entities() - .stream() - .filter(entitySelector -> entitySelector instanceof EntitySelector.Route) - .map(EntitySelector.Route.class::cast) - .anyMatch(route -> args.getGraphQLRoute().contains(route.routeId().toString())) - ) - .filter( - alert -> - args.getGraphQLStop() == null || - alert - .entities() - .stream() - .filter(entitySelector -> entitySelector instanceof EntitySelector.Stop) - .map(EntitySelector.Stop.class::cast) - .anyMatch(stop -> args.getGraphQLStop().contains(stop.stopId().toString())) - ) - .toList(); - } - /// Parse a string as a feed scoped id and apply a mapping function to the id. /// /// Returns null if the input is null or an invalid feed scoped id diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RentalVehicleImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RentalVehicleImpl.java index 9358e5d1ce3..d6af5de8dae 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RentalVehicleImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RentalVehicleImpl.java @@ -6,7 +6,7 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; import java.time.OffsetDateTime; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.service.vehiclerental.model.RentalVehicleFuel; import org.opentripplanner.service.vehiclerental.model.RentalVehicleType; @@ -92,6 +92,6 @@ private VehicleRentalVehicle getSource(DataFetchingEnvironment environment) { } private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } } diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteImpl.java index 8e900a94b06..973e82bc74b 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteImpl.java @@ -7,7 +7,7 @@ import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLBikesAllowed; @@ -275,11 +275,11 @@ private Iterable getTrips(DataFetchingEnvironment environment) { } private TransitAlertService getAlertService(DataFetchingEnvironment environment) { - return environment.getContext().transitAlertService(); + return environment.getContext().transitAlertService(); } private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } private Route getSource(DataFetchingEnvironment environment) { diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteTypeImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteTypeImpl.java index 09cedc48f22..518be56703c 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteTypeImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteTypeImpl.java @@ -3,7 +3,7 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; import java.util.stream.Collectors; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.model.RouteTypeModel; import org.opentripplanner.transit.model.network.Route; @@ -40,7 +40,7 @@ public DataFetcher> routes() { } private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } private RouteTypeModel getSource(DataFetchingEnvironment environment) { diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopCallImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopCallImpl.java index 543c45dc1b8..22e1efc9798 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopCallImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopCallImpl.java @@ -5,7 +5,7 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; import java.time.ZonedDateTime; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.model.CallRealTime; import org.opentripplanner.apis.gtfs.model.CallSchedule; @@ -27,13 +27,15 @@ public DataFetcher realTime() { return null; } var scheduledArrival = getZonedDateTime(environment, tripTime.getScheduledArrival()); - var estimatedArrival = scheduledArrival == null - ? null - : EstimatedTime.of(scheduledArrival, tripTime.getArrivalDelay()); + var estimatedArrival = + scheduledArrival == null + ? null + : EstimatedTime.of(scheduledArrival, tripTime.getArrivalDelay()); var scheduledDeparture = getZonedDateTime(environment, tripTime.getScheduledDeparture()); - var estimatedDeparture = scheduledDeparture == null - ? null - : EstimatedTime.of(scheduledDeparture, tripTime.getDepartureDelay()); + var estimatedDeparture = + scheduledDeparture == null + ? null + : EstimatedTime.of(scheduledDeparture, tripTime.getDepartureDelay()); return new CallRealTime(estimatedArrival, estimatedDeparture); }; } @@ -81,7 +83,7 @@ public DataFetcher stopLocation() { } private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } private ZonedDateTime getZonedDateTime(DataFetchingEnvironment environment, int time) { diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopCallOnTripOnServiceDateImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopCallOnTripOnServiceDateImpl.java index aef4ac1ca22..e563363a0c6 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopCallOnTripOnServiceDateImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopCallOnTripOnServiceDateImpl.java @@ -8,7 +8,8 @@ import org.opentripplanner.transit.model.timetable.TripOnServiceDate; public class StopCallOnTripOnServiceDateImpl - implements GraphQLDataFetchers.GraphQLStopCallOnTripOnServiceDate { + implements GraphQLDataFetchers.GraphQLStopCallOnTripOnServiceDate +{ @Override public DataFetcher stopCall() { diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java index 687f6c16d59..0779a308ef6 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java @@ -14,8 +14,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.Nullable; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.GraphQLUtils; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.mapping.ArrivalDepartureMapper; @@ -23,6 +23,7 @@ import org.opentripplanner.apis.gtfs.service.ApiTransitService; import org.opentripplanner.apis.gtfs.support.filter.PatternByDateFilterUtil; import org.opentripplanner.apis.gtfs.support.time.LocalDateRangeUtil; +import org.opentripplanner.apis.gtfs.support.time.OffsetDateTimeRangeUtil; import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.core.model.time.LocalDateRange; import org.opentripplanner.model.StopTimesInPattern; @@ -145,20 +146,28 @@ public DataFetcher> canceledCalls() { return environment -> { var args = new GraphQLTypes.GraphQLStopCanceledCallsArgs(environment.getArguments()); var rawRanges = args.getGraphQLServiceDateRanges(); - var serviceDateRanges = rawRanges == null - ? List.of(LocalDateRange.ofUnbounded()) - : LocalDateRangeUtil.mapRanges(rawRanges); + var serviceDateRanges = + rawRanges == null + ? List.of(LocalDateRange.ofUnbounded()) + : LocalDateRangeUtil.mapRanges(rawRanges); var arrivalDeparture = ArrivalDepartureMapper.map(args.getGraphQLArrivalDeparture()); + var callTimePeriods = OffsetDateTimeRangeUtil.mapRanges( + args.getGraphQLTimeRanges(), + "timeRanges" + ); var service = new ApiTransitService(getTransitService(environment)); return getValue( environment, - stop -> service.findCanceledStopCalls(stop, serviceDateRanges, arrivalDeparture), + stop -> + service.findCanceledStopCalls(stop, serviceDateRanges, callTimePeriods, arrivalDeparture), station -> station .getChildStops() .stream() .flatMap(stop -> - service.findCanceledStopCalls(stop, serviceDateRanges, arrivalDeparture).stream() + service + .findCanceledStopCalls(stop, serviceDateRanges, callTimePeriods, arrivalDeparture) + .stream() ) .collect(Collectors.toList()) ); @@ -491,7 +500,7 @@ public DataFetcher> transfers() { } private RegularTransferService getTransferService(DataFetchingEnvironment environment) { - return environment.getContext().transferService(); + return environment.getContext().transferService(); } @Override @@ -527,8 +536,10 @@ public DataFetcher vehicleType() { @Override public DataFetcher wheelchairBoarding() { return environment -> { - var boarding = getValue(environment, StopLocation::getWheelchairAccessibility, station -> - null + var boarding = getValue( + environment, + StopLocation::getWheelchairAccessibility, + station -> null ); return GraphQLUtils.toGraphQL(boarding); }; @@ -559,11 +570,11 @@ private Collection getRoutes(DataFetchingEnvironment environment) { } private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } private TransitAlertService getTransitAlertService(DataFetchingEnvironment environment) { - return environment.getContext().transitAlertService(); + return environment.getContext().transitAlertService(); } private static T getValue( diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TicketTypeImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TicketTypeImpl.java index e9da4b45207..3a4d3af7b52 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TicketTypeImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TicketTypeImpl.java @@ -12,7 +12,8 @@ public class TicketTypeImpl implements GraphQLDataFetchers.GraphQLTicketType { @Override public DataFetcher currency() { return environment -> - ((FareRuleSet) environment.getSource()).getFareAttribute() + ((FareRuleSet) environment.getSource()) + .getFareAttribute() .getPrice() .currency() .getCurrencyCode(); @@ -42,7 +43,8 @@ public DataFetcher price() { symbols.setDecimalSeparator('.'); format.setDecimalFormatSymbols(symbols); String price = format.format( - ((FareRuleSet) environment.getSource()).getFareAttribute() + ((FareRuleSet) environment.getSource()) + .getFareAttribute() .getPrice() .fractionalAmount() .floatValue() diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java index 51e9baae163..341571af0cb 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java @@ -15,8 +15,8 @@ import java.util.stream.Collectors; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.LineString; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.GraphQLUtils; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLBikesAllowed; @@ -142,9 +142,10 @@ public DataFetcher arrivalStoptime() { var args = new GraphQLTypes.GraphQLTripArrivalStoptimeArgs(environment.getArguments()); ZoneId timeZone = transitService.getTimeZone(); - LocalDate serviceDate = args.getGraphQLServiceDate() != null - ? ServiceDateUtils.parseString(args.getGraphQLServiceDate()) - : LocalDate.now(); + LocalDate serviceDate = + args.getGraphQLServiceDate() != null + ? ServiceDateUtils.parseString(args.getGraphQLServiceDate()) + : LocalDate.now(); TripPattern tripPattern = transitService.findPattern(trip, serviceDate); if (tripPattern == null) { @@ -197,9 +198,10 @@ public DataFetcher departureStoptime() { var args = new GraphQLTypes.GraphQLTripDepartureStoptimeArgs(environment.getArguments()); ZoneId timeZone = transitService.getTimeZone(); - LocalDate serviceDate = args.getGraphQLServiceDate() != null - ? ServiceDateUtils.parseString(args.getGraphQLServiceDate()) - : LocalDate.now(); + LocalDate serviceDate = + args.getGraphQLServiceDate() != null + ? ServiceDateUtils.parseString(args.getGraphQLServiceDate()) + : LocalDate.now(); TripPattern tripPattern = transitService.findPattern(trip, serviceDate); if (tripPattern == null) { @@ -358,9 +360,10 @@ public DataFetcher> stoptimesForDate() { var args = new GraphQLTypes.GraphQLTripStoptimesForDateArgs(environment.getArguments()); ZoneId timeZone = transitService.getTimeZone(); - LocalDate serviceDate = args.getGraphQLServiceDate() != null - ? ServiceDateUtils.parseString(args.getGraphQLServiceDate()) - : LocalDate.now(timeZone); + LocalDate serviceDate = + args.getGraphQLServiceDate() != null + ? ServiceDateUtils.parseString(args.getGraphQLServiceDate()) + : LocalDate.now(timeZone); TripPattern tripPattern = transitService.findPattern(trip, serviceDate); if (tripPattern == null) { @@ -443,15 +446,15 @@ private TripPattern getTripPattern(DataFetchingEnvironment environment) { } private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } private TransitAlertService getTransitAlertService(DataFetchingEnvironment environment) { - return environment.getContext().transitAlertService(); + return environment.getContext().transitAlertService(); } private RealtimeVehicleService getRealtimeVehiclesService(DataFetchingEnvironment environment) { - return environment.getContext().realTimeVehicleService(); + return environment.getContext().realTimeVehicleService(); } private Trip getSource(DataFetchingEnvironment environment) { diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripOnServiceDateImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripOnServiceDateImpl.java index f1f00fb590e..71f0d650d97 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripOnServiceDateImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripOnServiceDateImpl.java @@ -6,7 +6,7 @@ import java.time.LocalDate; import java.util.List; import javax.annotation.Nullable; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.model.RealTimeTripStateModel; import org.opentripplanner.model.TripTimeOnDate; @@ -143,7 +143,7 @@ private Timetable getTimetable( } private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } private Trip getTrip(DataFetchingEnvironment environment) { diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehiclePositionImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehiclePositionImpl.java index a7b7be3aa63..2c8fe101b32 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehiclePositionImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehiclePositionImpl.java @@ -3,7 +3,7 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; import java.time.OffsetDateTime; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle; import org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle.StopRelationship; @@ -24,7 +24,7 @@ public DataFetcher label() { @Override public DataFetcher lastUpdate() { return env -> { - var zoneId = env.getContext().transitService().getTimeZone(); + var zoneId = env.getContext().transitService().getTimeZone(); return getSource(env) .time() .map(time -> OffsetDateTime.ofInstant(time, zoneId)) diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/elevationProfileComponentImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/elevationProfileComponentImpl.java index 1c147acf90a..d1490e12943 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/elevationProfileComponentImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/elevationProfileComponentImpl.java @@ -6,7 +6,8 @@ import org.opentripplanner.street.model.elevation.ElevationProfile; public class elevationProfileComponentImpl - implements GraphQLDataFetchers.GraphQLElevationProfileComponent { + implements GraphQLDataFetchers.GraphQLElevationProfileComponent +{ @Override public DataFetcher distance() { diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/serviceTimeRangeImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/serviceTimeRangeImpl.java index d652925c73c..4579d1fd817 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/serviceTimeRangeImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/serviceTimeRangeImpl.java @@ -2,7 +2,7 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.transit.service.TransitService; @@ -19,6 +19,6 @@ public DataFetcher start() { } private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } } diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java index 5776ddb79ec..ace887cc5e7 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java @@ -4,10 +4,10 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; +import java.util.List; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.mapping.DirectionMapper; -import org.opentripplanner.apis.gtfs.mapping.StreetNoteMapper; import org.opentripplanner.model.plan.walkstep.WalkStep; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.street.model.elevation.ElevationProfile.Step; @@ -21,13 +21,9 @@ public DataFetcher absoluteDirection() { } @Override + @Deprecated public DataFetcher> alerts() { - return environment -> - getSource(environment) - .getStreetNotes() - .stream() - .map(StreetNoteMapper::mapStreetNoteToAlert) - .toList(); + return _ -> List.of(); } @Override diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stopAtDistanceImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stopAtDistanceImpl.java index 449ce0083d8..58724a0d143 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stopAtDistanceImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stopAtDistanceImpl.java @@ -3,7 +3,7 @@ import graphql.relay.Relay; import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.place.api.NearbyStop; import org.opentripplanner.transit.service.TransitService; @@ -31,7 +31,7 @@ public DataFetcher stop() { } private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); + return environment.getContext().transitService(); } private NearbyStop getSource(DataFetchingEnvironment environment) { diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index ae004bd402d..797d66142ce 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -32,6 +32,7 @@ import org.opentripplanner.apis.gtfs.model.CanceledTripsSummaryPattern; import org.opentripplanner.apis.gtfs.model.CanceledTripsSummaryRoute; import org.opentripplanner.apis.gtfs.model.FeedPublisher; +import org.opentripplanner.apis.gtfs.model.OffsetDateTimeRange; import org.opentripplanner.apis.gtfs.model.PlanPageInfo; import org.opentripplanner.apis.gtfs.model.RealTimeTripStateModel; import org.opentripplanner.apis.gtfs.model.RideHailingProvider; @@ -106,6 +107,7 @@ public interface GraphQLAgency { /** Alert of a current or upcoming disruption in public transportation */ public interface GraphQLAlert { + public DataFetcher> activityPeriods(); public DataFetcher agency(); public DataFetcher alertCause(); public DataFetcher alertDescriptionText(); @@ -128,6 +130,25 @@ public interface GraphQLAlert { public DataFetcher trip(); } + /** + * A connection to a list of alerts that follows + * [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm). + */ + public interface GraphQLAlertConnection { + public DataFetcher>> edges(); + public DataFetcher pageInfo(); + public DataFetcher totalCount(); + } + + /** + * An edge for the alert connection. Part of the + * [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm). + */ + public interface GraphQLAlertEdge { + public DataFetcher cursor(); + public DataFetcher node(); + } + /** Entity related to an alert */ public interface GraphQLAlertEntity extends TypeResolver {} @@ -355,9 +376,7 @@ public interface GraphQLEntrance { public DataFetcher entranceId(); public DataFetcher name(); public DataFetcher publicCode(); - public DataFetcher< - org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLWheelchairBoarding - > wheelchairAccessible(); + public DataFetcher wheelchairAccessible(); } /** A single use of an escalator. */ @@ -561,6 +580,18 @@ public interface GraphQLNotice { public DataFetcher text(); } + /** + * A range of time which can be unbounded in either direction. + * + * The start of the range is inclusive and the end is exclusive. + * A `null` start means that the range extends indefinitely into the past and a `null` end means + * that it extends indefinitely into the future. + */ + public interface GraphQLOffsetDateTimeRange { + public DataFetcher end(); + public DataFetcher start(); + } + public interface GraphQLOpeningHours { public DataFetcher> dates(); public DataFetcher osm(); @@ -697,6 +728,7 @@ public interface GraphQLQueryType { public DataFetcher> agencies(); public DataFetcher agency(); public DataFetcher> alerts(); + public DataFetcher> alertsConnection(); public DataFetcher bikePark(); public DataFetcher> bikeParks(); public DataFetcher bikeRentalStation(); @@ -792,12 +824,8 @@ public interface GraphQLRentalVehicleFuel { } public interface GraphQLRentalVehicleType { - public DataFetcher< - org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLFormFactor - > formFactor(); - public DataFetcher< - org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLPropulsionType - > propulsionType(); + public DataFetcher formFactor(); + public DataFetcher propulsionType(); } public interface GraphQLRentalVehicleTypeCount { @@ -931,9 +959,7 @@ public interface GraphQLStop { public DataFetcher url(); public DataFetcher vehicleMode(); public DataFetcher vehicleType(); - public DataFetcher< - org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLWheelchairBoarding - > wheelchairBoarding(); + public DataFetcher wheelchairBoarding(); public DataFetcher zoneId(); } @@ -1072,9 +1098,7 @@ public interface GraphQLTrip { public DataFetcher tripGeometry(); public DataFetcher tripHeadsign(); public DataFetcher tripShortName(); - public DataFetcher< - org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLWheelchairBoarding - > wheelchairAccessible(); + public DataFetcher wheelchairAccessible(); } /** diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java index a82488b390c..c34a303cb65 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java @@ -47,7 +47,8 @@ public static class GraphQLAgencyAlertsArgs { public GraphQLAgencyAlertsArgs(Map args) { if (args != null) { if (args.get("types") != null) { - this.types = ((List) args.get("types")).stream() + this.types = ((List) args.get("types")) + .stream() .map(item -> item instanceof GraphQLAgencyAlertType ? item @@ -171,6 +172,139 @@ public enum GraphQLAlertSeverityLevelType { WARNING, } + public static class GraphQLAlertsFilterInput { + + private List exclude; + private List include; + + public GraphQLAlertsFilterInput(Map args) { + if (args != null) { + if (args.get("exclude") != null) { + this.exclude = ((List>) args.get("exclude")) + .stream() + .map(o -> o == null ? null : new GraphQLAlertsFilterSelectInput(o)) + .collect(Collectors.toList()); + } + if (args.get("include") != null) { + this.include = ((List>) args.get("include")) + .stream() + .map(o -> o == null ? null : new GraphQLAlertsFilterSelectInput(o)) + .collect(Collectors.toList()); + } + } + } + + public List getGraphQLExclude() { + return this.exclude; + } + + public List getGraphQLInclude() { + return this.include; + } + + public void setGraphQLExclude(List exclude) { + this.exclude = exclude; + } + + public void setGraphQLInclude(List include) { + this.include = include; + } + } + + public static class GraphQLAlertsFilterSelectInput { + + private List activePeriods; + private List causes; + private List effects; + private List feeds; + private List severityLevels; + + public GraphQLAlertsFilterSelectInput(Map args) { + if (args != null) { + if (args.get("activePeriods") != null) { + this.activePeriods = ((List>) args.get("activePeriods")) + .stream() + .map(o -> o == null ? null : new GraphQLOffsetDateTimeRangeInput(o)) + .collect(Collectors.toList()); + } + if (args.get("causes") != null) { + this.causes = ((List) args.get("causes")) + .stream() + .map(item -> + item instanceof GraphQLAlertCauseType + ? item + : GraphQLAlertCauseType.valueOf((String) item) + ) + .map(GraphQLAlertCauseType.class::cast) + .collect(Collectors.toList()); + } + if (args.get("effects") != null) { + this.effects = ((List) args.get("effects")) + .stream() + .map(item -> + item instanceof GraphQLAlertEffectType + ? item + : GraphQLAlertEffectType.valueOf((String) item) + ) + .map(GraphQLAlertEffectType.class::cast) + .collect(Collectors.toList()); + } + this.feeds = (List) args.get("feeds"); + if (args.get("severityLevels") != null) { + this.severityLevels = ((List) args.get("severityLevels")) + .stream() + .map(item -> + item instanceof GraphQLAlertSeverityLevelType + ? item + : GraphQLAlertSeverityLevelType.valueOf((String) item) + ) + .map(GraphQLAlertSeverityLevelType.class::cast) + .collect(Collectors.toList()); + } + } + } + + public List getGraphQLActivePeriods() { + return this.activePeriods; + } + + public List getGraphQLCauses() { + return this.causes; + } + + public List getGraphQLEffects() { + return this.effects; + } + + public List getGraphQLFeeds() { + return this.feeds; + } + + public List getGraphQLSeverityLevels() { + return this.severityLevels; + } + + public void setGraphQLActivePeriods(List activePeriods) { + this.activePeriods = activePeriods; + } + + public void setGraphQLCauses(List causes) { + this.causes = causes; + } + + public void setGraphQLEffects(List effects) { + this.effects = effects; + } + + public void setGraphQLFeeds(List feeds) { + this.feeds = feeds; + } + + public void setGraphQLSeverityLevels(List severityLevels) { + this.severityLevels = severityLevels; + } + } + public static class GraphQLAlightPreferencesInput { private java.time.Duration slack; @@ -209,12 +343,14 @@ public static class GraphQLBicycleParkingPreferencesInput { public GraphQLBicycleParkingPreferencesInput(Map args) { if (args != null) { if (args.get("filters") != null) { - this.filters = ((List>) args.get("filters")).stream() + this.filters = ((List>) args.get("filters")) + .stream() .map(o -> o == null ? null : new GraphQLParkingFilterInput(o)) .collect(Collectors.toList()); } if (args.get("preferred") != null) { - this.preferred = ((List>) args.get("preferred")).stream() + this.preferred = ((List>) args.get("preferred")) + .stream() .map(o -> o == null ? null : new GraphQLParkingFilterInput(o)) .collect(Collectors.toList()); } @@ -515,12 +651,14 @@ public static class GraphQLCanceledTripsFilterInput { public GraphQLCanceledTripsFilterInput(Map args) { if (args != null) { if (args.get("exclude") != null) { - this.exclude = ((List>) args.get("exclude")).stream() + this.exclude = ((List>) args.get("exclude")) + .stream() .map(o -> o == null ? null : new GraphQLCanceledTripsFilterSelectInput(o)) .collect(Collectors.toList()); } if (args.get("include") != null) { - this.include = ((List>) args.get("include")).stream() + this.include = ((List>) args.get("include")) + .stream() .map(o -> o == null ? null : new GraphQLCanceledTripsFilterSelectInput(o)) .collect(Collectors.toList()); } @@ -547,22 +685,29 @@ public void setGraphQLInclude(List includ public static class GraphQLCanceledTripsFilterSelectInput { private List modes; + private List runningTimeRanges; private List serviceDateRanges; public GraphQLCanceledTripsFilterSelectInput(Map args) { if (args != null) { if (args.get("modes") != null) { - this.modes = ((List) args.get("modes")).stream() + this.modes = ((List) args.get("modes")) + .stream() .map(item -> item instanceof GraphQLTransitMode ? item : GraphQLTransitMode.valueOf((String) item) ) .map(GraphQLTransitMode.class::cast) .collect(Collectors.toList()); } + if (args.get("runningTimeRanges") != null) { + this.runningTimeRanges = ((List>) args.get("runningTimeRanges")) + .stream() + .map(o -> o == null ? null : new GraphQLOffsetDateTimeRangeInput(o)) + .collect(Collectors.toList()); + } if (args.get("serviceDateRanges") != null) { - this.serviceDateRanges = ((List>) args.get( - "serviceDateRanges" - )).stream() + this.serviceDateRanges = ((List>) args.get("serviceDateRanges")) + .stream() .map(o -> o == null ? null : new GraphQLLocalDateRangeInput(o)) .collect(Collectors.toList()); } @@ -573,6 +718,10 @@ public List getGraphQLModes() { return this.modes; } + public List getGraphQLRunningTimeRanges() { + return this.runningTimeRanges; + } + public List getGraphQLServiceDateRanges() { return this.serviceDateRanges; } @@ -581,6 +730,12 @@ public void setGraphQLModes(List modes) { this.modes = modes; } + public void setGraphQLRunningTimeRanges( + List runningTimeRanges + ) { + this.runningTimeRanges = runningTimeRanges; + } + public void setGraphQLServiceDateRanges(List serviceDateRanges) { this.serviceDateRanges = serviceDateRanges; } @@ -594,12 +749,14 @@ public static class GraphQLCanceledTripsSummaryFilterInput { public GraphQLCanceledTripsSummaryFilterInput(Map args) { if (args != null) { if (args.get("exclude") != null) { - this.exclude = ((List>) args.get("exclude")).stream() + this.exclude = ((List>) args.get("exclude")) + .stream() .map(o -> o == null ? null : new GraphQLCanceledTripsSummaryFilterSelectInput(o)) .collect(Collectors.toList()); } if (args.get("include") != null) { - this.include = ((List>) args.get("include")).stream() + this.include = ((List>) args.get("include")) + .stream() .map(o -> o == null ? null : new GraphQLCanceledTripsSummaryFilterSelectInput(o)) .collect(Collectors.toList()); } @@ -626,22 +783,29 @@ public void setGraphQLInclude(List public static class GraphQLCanceledTripsSummaryFilterSelectInput { private List modes; + private List runningTimeRanges; private List serviceDateRanges; public GraphQLCanceledTripsSummaryFilterSelectInput(Map args) { if (args != null) { if (args.get("modes") != null) { - this.modes = ((List) args.get("modes")).stream() + this.modes = ((List) args.get("modes")) + .stream() .map(item -> item instanceof GraphQLTransitMode ? item : GraphQLTransitMode.valueOf((String) item) ) .map(GraphQLTransitMode.class::cast) .collect(Collectors.toList()); } + if (args.get("runningTimeRanges") != null) { + this.runningTimeRanges = ((List>) args.get("runningTimeRanges")) + .stream() + .map(o -> o == null ? null : new GraphQLOffsetDateTimeRangeInput(o)) + .collect(Collectors.toList()); + } if (args.get("serviceDateRanges") != null) { - this.serviceDateRanges = ((List>) args.get( - "serviceDateRanges" - )).stream() + this.serviceDateRanges = ((List>) args.get("serviceDateRanges")) + .stream() .map(o -> o == null ? null : new GraphQLLocalDateRangeInput(o)) .collect(Collectors.toList()); } @@ -652,6 +816,10 @@ public List getGraphQLModes() { return this.modes; } + public List getGraphQLRunningTimeRanges() { + return this.runningTimeRanges; + } + public List getGraphQLServiceDateRanges() { return this.serviceDateRanges; } @@ -660,6 +828,12 @@ public void setGraphQLModes(List modes) { this.modes = modes; } + public void setGraphQLRunningTimeRanges( + List runningTimeRanges + ) { + this.runningTimeRanges = runningTimeRanges; + } + public void setGraphQLServiceDateRanges(List serviceDateRanges) { this.serviceDateRanges = serviceDateRanges; } @@ -693,12 +867,14 @@ public static class GraphQLCarParkingPreferencesInput { public GraphQLCarParkingPreferencesInput(Map args) { if (args != null) { if (args.get("filters") != null) { - this.filters = ((List>) args.get("filters")).stream() + this.filters = ((List>) args.get("filters")) + .stream() .map(o -> o == null ? null : new GraphQLParkingFilterInput(o)) .collect(Collectors.toList()); } if (args.get("preferred") != null) { - this.preferred = ((List>) args.get("preferred")).stream() + this.preferred = ((List>) args.get("preferred")) + .stream() .map(o -> o == null ? null : new GraphQLParkingFilterInput(o)) .collect(Collectors.toList()); } @@ -1040,7 +1216,8 @@ public static class GraphQLFeedAlertsArgs { public GraphQLFeedAlertsArgs(Map args) { if (args != null) { if (args.get("types") != null) { - this.types = ((List) args.get("types")).stream() + this.types = ((List) args.get("types")) + .stream() .map(item -> item instanceof GraphQLFeedAlertType ? item @@ -1587,7 +1764,8 @@ public static class GraphQLLegIntermediateStopsArgs { public GraphQLLegIntermediateStopsArgs(Map args) { if (args != null) { if (args.get("include") != null) { - this.include = ((List) args.get("include")).stream() + this.include = ((List) args.get("include")) + .stream() .map(item -> item instanceof GraphQLStopType ? item : GraphQLStopType.valueOf((String) item) ) @@ -1615,9 +1793,10 @@ public static class GraphQLLegNextLegsArgs { public GraphQLLegNextLegsArgs(Map args) { if (args != null) { if (args.get("destinationModesWithParentStation") != null) { - this.destinationModesWithParentStation = ((List) args.get( - "destinationModesWithParentStation" - )).stream() + this.destinationModesWithParentStation = ( + (List) args.get("destinationModesWithParentStation") + ) + .stream() .map(item -> item instanceof GraphQLTransitMode ? item : GraphQLTransitMode.valueOf((String) item) ) @@ -1626,9 +1805,10 @@ public GraphQLLegNextLegsArgs(Map args) { } this.numberOfLegs = (Integer) args.get("numberOfLegs"); if (args.get("originModesWithParentStation") != null) { - this.originModesWithParentStation = ((List) args.get( - "originModesWithParentStation" - )).stream() + this.originModesWithParentStation = ( + (List) args.get("originModesWithParentStation") + ) + .stream() .map(item -> item instanceof GraphQLTransitMode ? item : GraphQLTransitMode.valueOf((String) item) ) @@ -1676,9 +1856,10 @@ public static class GraphQLLegPreviousLegsArgs { public GraphQLLegPreviousLegsArgs(Map args) { if (args != null) { if (args.get("destinationModesWithParentStation") != null) { - this.destinationModesWithParentStation = ((List) args.get( - "destinationModesWithParentStation" - )).stream() + this.destinationModesWithParentStation = ( + (List) args.get("destinationModesWithParentStation") + ) + .stream() .map(item -> item instanceof GraphQLTransitMode ? item : GraphQLTransitMode.valueOf((String) item) ) @@ -1687,9 +1868,10 @@ public GraphQLLegPreviousLegsArgs(Map args) { } this.numberOfLegs = (Integer) args.get("numberOfLegs"); if (args.get("originModesWithParentStation") != null) { - this.originModesWithParentStation = ((List) args.get( - "originModesWithParentStation" - )).stream() + this.originModesWithParentStation = ( + (List) args.get("originModesWithParentStation") + ) + .stream() .map(item -> item instanceof GraphQLTransitMode ? item : GraphQLTransitMode.valueOf((String) item) ) @@ -1830,6 +2012,35 @@ public enum GraphQLOccupancyStatus { STANDING_ROOM_ONLY, } + public static class GraphQLOffsetDateTimeRangeInput { + + private java.time.OffsetDateTime end; + private java.time.OffsetDateTime start; + + public GraphQLOffsetDateTimeRangeInput(Map args) { + if (args != null) { + this.end = (java.time.OffsetDateTime) args.get("end"); + this.start = (java.time.OffsetDateTime) args.get("start"); + } + } + + public java.time.OffsetDateTime getGraphQLEnd() { + return this.end; + } + + public java.time.OffsetDateTime getGraphQLStart() { + return this.start; + } + + public void setGraphQLEnd(java.time.OffsetDateTime end) { + this.end = end; + } + + public void setGraphQLStart(java.time.OffsetDateTime start) { + this.start = start; + } + } + public static class GraphQLOpeningHoursDatesArgs { private List dates; @@ -1866,12 +2077,14 @@ public static class GraphQLParkingFilterInput { public GraphQLParkingFilterInput(Map args) { if (args != null) { if (args.get("not") != null) { - this.not = ((List>) args.get("not")).stream() + this.not = ((List>) args.get("not")) + .stream() .map(o -> o == null ? null : new GraphQLParkingFilterOperationInput(o)) .collect(Collectors.toList()); } if (args.get("select") != null) { - this.select = ((List>) args.get("select")).stream() + this.select = ((List>) args.get("select")) + .stream() .map(o -> o == null ? null : new GraphQLParkingFilterOperationInput(o)) .collect(Collectors.toList()); } @@ -1921,7 +2134,8 @@ public static class GraphQLPatternAlertsArgs { public GraphQLPatternAlertsArgs(Map args) { if (args != null) { if (args.get("types") != null) { - this.types = ((List) args.get("types")).stream() + this.types = ((List) args.get("types")) + .stream() .map(item -> item instanceof GraphQLPatternAlertType ? item @@ -1944,24 +2158,40 @@ public void setGraphQLTypes(List types) { public static class GraphQLPatternCanceledTripsArgs { + private List runningTimeRanges; private List serviceDateRanges; public GraphQLPatternCanceledTripsArgs(Map args) { if (args != null) { + if (args.get("runningTimeRanges") != null) { + this.runningTimeRanges = ((List>) args.get("runningTimeRanges")) + .stream() + .map(o -> o == null ? null : new GraphQLOffsetDateTimeRangeInput(o)) + .collect(Collectors.toList()); + } if (args.get("serviceDateRanges") != null) { - this.serviceDateRanges = ((List>) args.get( - "serviceDateRanges" - )).stream() + this.serviceDateRanges = ((List>) args.get("serviceDateRanges")) + .stream() .map(o -> o == null ? null : new GraphQLLocalDateRangeInput(o)) .collect(Collectors.toList()); } } } + public List getGraphQLRunningTimeRanges() { + return this.runningTimeRanges; + } + public List getGraphQLServiceDateRanges() { return this.serviceDateRanges; } + public void setGraphQLRunningTimeRanges( + List runningTimeRanges + ) { + this.runningTimeRanges = runningTimeRanges; + } + public void setGraphQLServiceDateRanges(List serviceDateRanges) { this.serviceDateRanges = serviceDateRanges; } @@ -2255,7 +2485,8 @@ public static class GraphQLPlanModesInput { public GraphQLPlanModesInput(Map args) { if (args != null) { if (args.get("direct") != null) { - this.direct = ((List) args.get("direct")).stream() + this.direct = ((List) args.get("direct")) + .stream() .map(item -> item instanceof GraphQLPlanDirectMode ? item @@ -2512,7 +2743,8 @@ public static class GraphQLPlanTransitModesInput { public GraphQLPlanTransitModesInput(Map args) { if (args != null) { if (args.get("access") != null) { - this.access = ((List) args.get("access")).stream() + this.access = ((List) args.get("access")) + .stream() .map(item -> item instanceof GraphQLPlanAccessMode ? item @@ -2522,7 +2754,8 @@ public GraphQLPlanTransitModesInput(Map args) { .collect(Collectors.toList()); } if (args.get("egress") != null) { - this.egress = ((List) args.get("egress")).stream() + this.egress = ((List) args.get("egress")) + .stream() .map(item -> item instanceof GraphQLPlanEgressMode ? item @@ -2532,7 +2765,8 @@ public GraphQLPlanTransitModesInput(Map args) { .collect(Collectors.toList()); } if (args.get("transfer") != null) { - this.transfer = ((List) args.get("transfer")).stream() + this.transfer = ((List) args.get("transfer")) + .stream() .map(item -> item instanceof GraphQLPlanTransferMode ? item @@ -2542,7 +2776,8 @@ public GraphQLPlanTransitModesInput(Map args) { .collect(Collectors.toList()); } if (args.get("transit") != null) { - this.transit = ((List>) args.get("transit")).stream() + this.transit = ((List>) args.get("transit")) + .stream() .map(o -> o == null ? null : new GraphQLPlanTransitModePreferenceInput(o)) .collect(Collectors.toList()); } @@ -2723,7 +2958,8 @@ public static class GraphQLQueryTypeAlertsArgs { public GraphQLQueryTypeAlertsArgs(Map args) { if (args != null) { if (args.get("cause") != null) { - this.cause = ((List) args.get("cause")).stream() + this.cause = ((List) args.get("cause")) + .stream() .map(item -> item instanceof GraphQLAlertCauseType ? item @@ -2733,7 +2969,8 @@ public GraphQLQueryTypeAlertsArgs(Map args) { .collect(Collectors.toList()); } if (args.get("effect") != null) { - this.effect = ((List) args.get("effect")).stream() + this.effect = ((List) args.get("effect")) + .stream() .map(item -> item instanceof GraphQLAlertEffectType ? item @@ -2745,7 +2982,8 @@ public GraphQLQueryTypeAlertsArgs(Map args) { this.feeds = (List) args.get("feeds"); this.route = (List) args.get("route"); if (args.get("severityLevel") != null) { - this.severityLevel = ((List) args.get("severityLevel")).stream() + this.severityLevel = ((List) args.get("severityLevel")) + .stream() .map(item -> item instanceof GraphQLAlertSeverityLevelType ? item @@ -2807,6 +3045,70 @@ public void setGraphQLStop(List stop) { } } + public static class GraphQLQueryTypeAlertsConnectionArgs { + + private String after; + private String before; + private List filters; + private Integer first; + private Integer last; + + public GraphQLQueryTypeAlertsConnectionArgs(Map args) { + if (args != null) { + this.after = (String) args.get("after"); + this.before = (String) args.get("before"); + if (args.get("filters") != null) { + this.filters = ((List>) args.get("filters")) + .stream() + .map(o -> o == null ? null : new GraphQLAlertsFilterInput(o)) + .collect(Collectors.toList()); + } + this.first = (Integer) args.get("first"); + this.last = (Integer) args.get("last"); + } + } + + public String getGraphQLAfter() { + return this.after; + } + + public String getGraphQLBefore() { + return this.before; + } + + public List getGraphQLFilters() { + return this.filters; + } + + public Integer getGraphQLFirst() { + return this.first; + } + + public Integer getGraphQLLast() { + return this.last; + } + + public void setGraphQLAfter(String after) { + this.after = after; + } + + public void setGraphQLBefore(String before) { + this.before = before; + } + + public void setGraphQLFilters(List filters) { + this.filters = filters; + } + + public void setGraphQLFirst(Integer first) { + this.first = first; + } + + public void setGraphQLLast(Integer last) { + this.last = last; + } + } + public static class GraphQLQueryTypeBikeParkArgs { private String id; @@ -2877,7 +3179,8 @@ public GraphQLQueryTypeCanceledTripsArgs(Map args) { this.after = (String) args.get("after"); this.before = (String) args.get("before"); if (args.get("filters") != null) { - this.filters = ((List>) args.get("filters")).stream() + this.filters = ((List>) args.get("filters")) + .stream() .map(o -> o == null ? null : new GraphQLCanceledTripsFilterInput(o)) .collect(Collectors.toList()); } @@ -2934,7 +3237,8 @@ public static class GraphQLQueryTypeCanceledTripsSummaryArgs { public GraphQLQueryTypeCanceledTripsSummaryArgs(Map args) { if (args != null) { if (args.get("filters") != null) { - this.filters = ((List>) args.get("filters")).stream() + this.filters = ((List>) args.get("filters")) + .stream() .map(o -> o == null ? null : new GraphQLCanceledTripsSummaryFilterInput(o)) .collect(Collectors.toList()); } @@ -3226,14 +3530,16 @@ public GraphQLQueryTypeNearestArgs(Map args) { (Map) args.get("filterByIds") ); if (args.get("filterByModes") != null) { - this.filterByModes = ((List) args.get("filterByModes")).stream() + this.filterByModes = ((List) args.get("filterByModes")) + .stream() .map(item -> item instanceof GraphQLMode ? item : GraphQLMode.valueOf((String) item)) .map(GraphQLMode.class::cast) .collect(Collectors.toList()); } this.filterByNetwork = (List) args.get("filterByNetwork"); if (args.get("filterByPlaceTypes") != null) { - this.filterByPlaceTypes = ((List) args.get("filterByPlaceTypes")).stream() + this.filterByPlaceTypes = ((List) args.get("filterByPlaceTypes")) + .stream() .map(item -> item instanceof GraphQLFilterPlaceType ? item @@ -3507,9 +3813,8 @@ public GraphQLQueryTypePlanArgs(Map args) { this.heuristicStepsPerMainStep = (Integer) args.get("heuristicStepsPerMainStep"); this.ignoreRealtimeUpdates = (Boolean) args.get("ignoreRealtimeUpdates"); if (args.get("intermediatePlaces") != null) { - this.intermediatePlaces = ((List>) args.get( - "intermediatePlaces" - )).stream() + this.intermediatePlaces = ((List>) args.get("intermediatePlaces")) + .stream() .map(o -> o == null ? null : new GraphQLInputCoordinatesInput(o)) .collect(Collectors.toList()); } @@ -3547,7 +3852,8 @@ public GraphQLQueryTypePlanArgs(Map args) { this.toPlace = (String) args.get("toPlace"); this.transferPenalty = (Integer) args.get("transferPenalty"); if (args.get("transportModes") != null) { - this.transportModes = ((List>) args.get("transportModes")).stream() + this.transportModes = ((List>) args.get("transportModes")) + .stream() .map(o -> o == null ? null : new GraphQLTransportModeInput(o)) .collect(Collectors.toList()); } @@ -3556,7 +3862,8 @@ public GraphQLQueryTypePlanArgs(Map args) { (Map) args.get("unpreferred") ); if (args.get("via") != null) { - this.via = ((List>) args.get("via")).stream() + this.via = ((List>) args.get("via")) + .stream() .map(o -> o == null ? null : new GraphQLPlanViaLocationInput(o)) .collect(Collectors.toList()); } @@ -4129,7 +4436,8 @@ public GraphQLQueryTypePlanConnectionArgs(Map args) { ); this.searchWindow = (java.time.Duration) args.get("searchWindow"); if (args.get("via") != null) { - this.via = ((List>) args.get("via")).stream() + this.via = ((List>) args.get("via")) + .stream() .map(o -> o == null ? null : new GraphQLPlanViaLocationInput(o)) .collect(Collectors.toList()); } @@ -4276,7 +4584,8 @@ public static class GraphQLQueryTypeRentalVehiclesArgs { public GraphQLQueryTypeRentalVehiclesArgs(Map args) { if (args != null) { if (args.get("formFactors") != null) { - this.formFactors = ((List) args.get("formFactors")).stream() + this.formFactors = ((List) args.get("formFactors")) + .stream() .map(item -> item instanceof GraphQLFormFactor ? item : GraphQLFormFactor.valueOf((String) item) ) @@ -4340,7 +4649,8 @@ public GraphQLQueryTypeRoutesArgs(Map args) { (Map) args.get("serviceDates") ); if (args.get("transportModes") != null) { - this.transportModes = ((List) args.get("transportModes")).stream() + this.transportModes = ((List) args.get("transportModes")) + .stream() .map(item -> item instanceof GraphQLMode ? item : GraphQLMode.valueOf((String) item)) .map(GraphQLMode.class::cast) .collect(Collectors.toList()); @@ -4867,7 +5177,8 @@ public static class GraphQLRouteAlertsArgs { public GraphQLRouteAlertsArgs(Map args) { if (args != null) { if (args.get("types") != null) { - this.types = ((List) args.get("types")).stream() + this.types = ((List) args.get("types")) + .stream() .map(item -> item instanceof GraphQLRouteAlertType ? item @@ -5099,7 +5410,8 @@ public static class GraphQLStopAlertsArgs { public GraphQLStopAlertsArgs(Map args) { if (args != null) { if (args.get("types") != null) { - this.types = ((List) args.get("types")).stream() + this.types = ((List) args.get("types")) + .stream() .map(item -> item instanceof GraphQLStopAlertType ? item @@ -5124,6 +5436,7 @@ public static class GraphQLStopCanceledCallsArgs { private GraphQLArrivalDeparture arrivalDeparture; private List serviceDateRanges; + private List timeRanges; public GraphQLStopCanceledCallsArgs(Map args) { if (args != null) { @@ -5135,12 +5448,17 @@ public GraphQLStopCanceledCallsArgs(Map args) { ); } if (args.get("serviceDateRanges") != null) { - this.serviceDateRanges = ((List>) args.get( - "serviceDateRanges" - )).stream() + this.serviceDateRanges = ((List>) args.get("serviceDateRanges")) + .stream() .map(o -> o == null ? null : new GraphQLLocalDateRangeInput(o)) .collect(Collectors.toList()); } + if (args.get("timeRanges") != null) { + this.timeRanges = ((List>) args.get("timeRanges")) + .stream() + .map(o -> o == null ? null : new GraphQLOffsetDateTimeRangeInput(o)) + .collect(Collectors.toList()); + } } } @@ -5152,6 +5470,10 @@ public List getGraphQLServiceDateRanges() { return this.serviceDateRanges; } + public List getGraphQLTimeRanges() { + return this.timeRanges; + } + public void setGraphQLArrivalDeparture(GraphQLArrivalDeparture arrivalDeparture) { this.arrivalDeparture = arrivalDeparture; } @@ -5159,6 +5481,10 @@ public void setGraphQLArrivalDeparture(GraphQLArrivalDeparture arrivalDeparture) public void setGraphQLServiceDateRanges(List serviceDateRanges) { this.serviceDateRanges = serviceDateRanges; } + + public void setGraphQLTimeRanges(List timeRanges) { + this.timeRanges = timeRanges; + } } public static class GraphQLStopDescArgs { @@ -5616,12 +5942,14 @@ public static class GraphQLTransitFilterInput { public GraphQLTransitFilterInput(Map args) { if (args != null) { if (args.get("exclude") != null) { - this.exclude = ((List>) args.get("exclude")).stream() + this.exclude = ((List>) args.get("exclude")) + .stream() .map(o -> o == null ? null : new GraphQLTransitFilterSelectInput(o)) .collect(Collectors.toList()); } if (args.get("include") != null) { - this.include = ((List>) args.get("include")).stream() + this.include = ((List>) args.get("include")) + .stream() .map(o -> o == null ? null : new GraphQLTransitFilterSelectInput(o)) .collect(Collectors.toList()); } @@ -5730,7 +6058,8 @@ public GraphQLTransitPreferencesInput(Map args) { this.alight = new GraphQLAlightPreferencesInput((Map) args.get("alight")); this.board = new GraphQLBoardPreferencesInput((Map) args.get("board")); if (args.get("filters") != null) { - this.filters = ((List>) args.get("filters")).stream() + this.filters = ((List>) args.get("filters")) + .stream() .map(o -> o == null ? null : new GraphQLTransitFilterInput(o)) .collect(Collectors.toList()); } @@ -5919,7 +6248,8 @@ public static class GraphQLTripAlertsArgs { public GraphQLTripAlertsArgs(Map args) { if (args != null) { if (args.get("types") != null) { - this.types = ((List) args.get("types")).stream() + this.types = ((List) args.get("types")) + .stream() .map(item -> item instanceof GraphQLTripAlertType ? item @@ -6092,12 +6422,14 @@ public static class GraphQLVehicleParkingInput { public GraphQLVehicleParkingInput(Map args) { if (args != null) { if (args.get("filters") != null) { - this.filters = ((List>) args.get("filters")).stream() + this.filters = ((List>) args.get("filters")) + .stream() .map(o -> o == null ? null : new GraphQLParkingFilterInput(o)) .collect(Collectors.toList()); } if (args.get("preferred") != null) { - this.preferred = ((List>) args.get("preferred")).stream() + this.preferred = ((List>) args.get("preferred")) + .stream() .map(o -> o == null ? null : new GraphQLParkingFilterInput(o)) .collect(Collectors.toList()); } diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml index 54c5faf1d19..3d21729de59 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml @@ -41,6 +41,8 @@ config: RouteType: org.opentripplanner.apis.gtfs.model.RouteTypeModel#RouteTypeModel Alert: org.opentripplanner.routing.alertpatch.TransitAlert#TransitAlert AlertCauseType: org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLAlertCauseType#GraphQLAlertCauseType + AlertConnection: org.opentripplanner.framework.graphql.CountedConnection#CountedConnection + AlertEdge: graphql.relay.Edge#Edge AlertEffectType: org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLAlertEffectType#GraphQLAlertEffectType AlertSeverityLevelType: org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLAlertSeverityLevelType#GraphQLAlertSeverityLevelType BikePark: org.opentripplanner.service.vehicleparking.model.VehicleParking#VehicleParking @@ -147,4 +149,5 @@ config: CanceledTripsSummaryPattern: org.opentripplanner.apis.gtfs.model.CanceledTripsSummaryPattern#CanceledTripsSummaryPattern CanceledTripsSummaryRoute: org.opentripplanner.apis.gtfs.model.CanceledTripsSummaryRoute#CanceledTripsSummaryRoute Notice: org.opentripplanner.transit.model.basic.Notice + OffsetDateTimeRange: org.opentripplanner.apis.gtfs.model.OffsetDateTimeRange#OffsetDateTimeRange RealTimeTripState: org.opentripplanner.apis.gtfs.model.RealTimeTripStateModel#RealTimeTripStateModel diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertCauseMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertCauseMapper.java index 502fc3ea34a..e13465031fb 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertCauseMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertCauseMapper.java @@ -31,4 +31,24 @@ public static GraphQLAlertCauseType getGraphQLCause(AlertCause cause) { case MEDICAL_EMERGENCY -> GraphQLAlertCauseType.MEDICAL_EMERGENCY; }; } + + /** + * Returns the internal {@link AlertCause} for a GraphQL API cause. + */ + public static AlertCause getAlertCause(GraphQLAlertCauseType cause) { + return switch (cause) { + case UNKNOWN_CAUSE -> AlertCause.UNKNOWN_CAUSE; + case OTHER_CAUSE -> AlertCause.OTHER_CAUSE; + case TECHNICAL_PROBLEM -> AlertCause.TECHNICAL_PROBLEM; + case STRIKE -> AlertCause.STRIKE; + case DEMONSTRATION -> AlertCause.DEMONSTRATION; + case ACCIDENT -> AlertCause.ACCIDENT; + case HOLIDAY -> AlertCause.HOLIDAY; + case WEATHER -> AlertCause.WEATHER; + case MAINTENANCE -> AlertCause.MAINTENANCE; + case CONSTRUCTION -> AlertCause.CONSTRUCTION; + case POLICE_ACTIVITY -> AlertCause.POLICE_ACTIVITY; + case MEDICAL_EMERGENCY -> AlertCause.MEDICAL_EMERGENCY; + }; + } } diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertEffectMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertEffectMapper.java index 6bed185d593..c6bf6ae81a0 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertEffectMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertEffectMapper.java @@ -30,4 +30,23 @@ public static GraphQLAlertEffectType getGraphQLEffect(AlertEffect effect) { case ACCESSIBILITY_ISSUE -> GraphQLAlertEffectType.ACCESSIBILITY_ISSUE; }; } + + /** + * Returns the internal {@link AlertEffect} for a GraphQL API effect. + */ + public static AlertEffect getAlertEffect(GraphQLAlertEffectType effect) { + return switch (effect) { + case NO_SERVICE -> AlertEffect.NO_SERVICE; + case REDUCED_SERVICE -> AlertEffect.REDUCED_SERVICE; + case SIGNIFICANT_DELAYS -> AlertEffect.SIGNIFICANT_DELAYS; + case DETOUR -> AlertEffect.DETOUR; + case ADDITIONAL_SERVICE -> AlertEffect.ADDITIONAL_SERVICE; + case MODIFIED_SERVICE -> AlertEffect.MODIFIED_SERVICE; + case OTHER_EFFECT -> AlertEffect.OTHER_EFFECT; + case UNKNOWN_EFFECT -> AlertEffect.UNKNOWN_EFFECT; + case STOP_MOVED -> AlertEffect.STOP_MOVED; + case NO_EFFECT -> AlertEffect.NO_EFFECT; + case ACCESSIBILITY_ISSUE -> AlertEffect.ACCESSIBILITY_ISSUE; + }; + } } diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertsConnectionFilterMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertsConnectionFilterMapper.java new file mode 100644 index 00000000000..cdd5874b8e4 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertsConnectionFilterMapper.java @@ -0,0 +1,147 @@ +package org.opentripplanner.apis.gtfs.mapping; + +import java.util.List; +import javax.annotation.Nullable; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLAlertCauseType; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLAlertEffectType; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLAlertSeverityLevelType; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLAlertsFilterInput; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLAlertsFilterSelectInput; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLOffsetDateTimeRangeInput; +import org.opentripplanner.apis.support.InvalidInputException; +import org.opentripplanner.core.model.time.TimePeriod; +import org.opentripplanner.routing.alertpatch.AlertCause; +import org.opentripplanner.routing.alertpatch.AlertEffect; +import org.opentripplanner.routing.alertpatch.AlertSeverity; +import org.opentripplanner.transit.api.request.TransitAlertRequest; +import org.opentripplanner.transit.model.filter.selector.FilterRequest; +import org.opentripplanner.transit.model.filter.transit.TransitAlertSelectRequest; +import org.opentripplanner.utils.collection.CollectionUtils; + +/** + * Maps the GraphQL {@code alertsConnection} filter input into a {@link TransitAlertRequest}. + *

+ * Each filter is mapped to a {@link FilterRequest} with select/not semantics: an alert matches a + * filter if it matches at least one of the {@code include} selectors and none of the + * {@code exclude} selectors. The filters themselves are combined with OR semantics. + */ +public class AlertsConnectionFilterMapper { + + public static TransitAlertRequest map(@Nullable List filters) { + if (CollectionUtils.isEmpty(filters)) { + return TransitAlertRequest.of().build(); + } + return TransitAlertRequest.of() + .withFilters(filters.stream().map(AlertsConnectionFilterMapper::toFilterRequest).toList()) + .build(); + } + + private static FilterRequest toFilterRequest( + GraphQLAlertsFilterInput filter + ) { + var includes = filter.getGraphQLInclude(); + var excludes = filter.getGraphQLExclude(); + CollectionUtils.requireNullOrNonEmpty(includes, "filters.include"); + CollectionUtils.requireNullOrNonEmpty(excludes, "filters.exclude"); + + var builder = FilterRequest.of(); + if (includes != null) { + includes + .stream() + .map(select -> toSelectRequest(select, "filters.include")) + .forEach(builder::addSelect); + } + if (excludes != null) { + excludes + .stream() + .map(select -> toSelectRequest(select, "filters.exclude")) + .forEach(builder::addNot); + } + return builder.build(); + } + + private static TransitAlertSelectRequest toSelectRequest( + @Nullable GraphQLAlertsFilterSelectInput select, + String path + ) { + if (select == null) { + throw new InvalidInputException("'%s' must not contain null values.".formatted(path)); + } + return TransitAlertSelectRequest.of() + .withFeeds(requireNullOrNonEmpty(select.getGraphQLFeeds(), path + ".feeds")) + .withSeverityLevels(severities(select.getGraphQLSeverityLevels(), path + ".severityLevels")) + .withCauses(causes(select.getGraphQLCauses(), path + ".causes")) + .withEffects(effects(select.getGraphQLEffects(), path + ".effects")) + .withTimePeriods(activePeriods(select.getGraphQLActivePeriods(), path + ".activePeriods")) + .build(); + } + + @Nullable + private static List severities( + @Nullable List values, + String path + ) { + requireNullOrNonEmpty(values, path); + return values == null + ? null + : values + .stream() + .flatMap(s -> SeverityMapper.getAlertSeverities(s).stream()) + .toList(); + } + + @Nullable + private static List causes( + @Nullable List values, + String path + ) { + requireNullOrNonEmpty(values, path); + return values == null ? null : values.stream().map(AlertCauseMapper::getAlertCause).toList(); + } + + @Nullable + private static List effects( + @Nullable List values, + String path + ) { + requireNullOrNonEmpty(values, path); + return values == null ? null : values.stream().map(AlertEffectMapper::getAlertEffect).toList(); + } + + @Nullable + private static List activePeriods( + @Nullable List ranges, + String path + ) { + requireNullOrNonEmpty(ranges, path); + return ranges == null + ? null + : ranges.stream().map(AlertsConnectionFilterMapper::activePeriod).toList(); + } + + private static TimePeriod activePeriod(GraphQLOffsetDateTimeRangeInput range) { + var start = range.getGraphQLStart() != null ? range.getGraphQLStart().toInstant() : null; + var end = range.getGraphQLEnd() != null ? range.getGraphQLEnd().toInstant() : null; + return TimePeriod.of(start, end); + } + + /** + * A dimension is either unset or has at least one non-null value. An empty list would filter + * away everything, which is never what the caller wants, so it is rejected. + */ + @Nullable + private static List requireNullOrNonEmpty(@Nullable List values, String path) { + if (values == null) { + return null; + } + if (values.isEmpty()) { + throw new InvalidInputException( + "'%s' must be either null or have at least one entry.".formatted(path) + ); + } + if (values.contains(null)) { + throw new InvalidInputException("'%s' must not contain null values.".formatted(path)); + } + return values; + } +} diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/CanceledTripsFilterMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/CanceledTripsFilterMapper.java index d962d230a2b..de36481b97f 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/CanceledTripsFilterMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/CanceledTripsFilterMapper.java @@ -1,7 +1,9 @@ package org.opentripplanner.apis.gtfs.mapping; import graphql.schema.DataFetchingEnvironment; +import java.text.ParseException; import java.time.LocalDate; +import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -10,17 +12,23 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.Nullable; +import org.opentripplanner.apis.gtfs.support.time.OffsetDateTimeRangeUtil; import org.opentripplanner.apis.support.InvalidInputException; import org.opentripplanner.core.model.time.LocalDateRange; +import org.opentripplanner.core.model.time.TimePeriod; import org.opentripplanner.transit.api.request.TripOnServiceDateRequest; import org.opentripplanner.transit.model.basic.MainAndSubMode; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.filter.selector.FilterRequest; import org.opentripplanner.transit.model.filter.transit.TripOnServiceDateSelectRequest; import org.opentripplanner.utils.collection.CollectionUtils; +import org.opentripplanner.utils.time.OffsetDateTimeParser; public class CanceledTripsFilterMapper { + private static final String RUNNING_TIME_RANGES = "runningTimeRanges"; + private static final String RUNNING_TIME_RANGES_PATH = "filters.*.runningTimeRanges"; + public static TripOnServiceDateRequest mapToTripOnServiceDateRequest( DataFetchingEnvironment env ) { @@ -57,7 +65,8 @@ private static FilterRequest toFilterRequest( private static TripOnServiceDateSelectRequest toSelectRequest(List> inputs) { var modes = toTransitModes(inputs); var serviceDateRanges = toServiceDateRanges(inputs); - if (modes == null && serviceDateRanges == null) { + var runningTimePeriods = toRunningTimePeriods(inputs); + if (modes == null && serviceDateRanges == null && runningTimePeriods == null) { return null; } @@ -68,6 +77,9 @@ private static TripOnServiceDateSelectRequest toSelectRequest(List rangeInput) ); } + @Nullable + private static List toRunningTimePeriods(List> inputs) { + if (inputs == null) { + return null; + } + var periods = inputs + .stream() + .flatMap(input -> { + var rangeInputs = mapList(input.get(RUNNING_TIME_RANGES), RUNNING_TIME_RANGES_PATH); + if (rangeInputs == null) { + return Stream.of(); + } + OffsetDateTimeRangeUtil.requireNonEmpty(rangeInputs, RUNNING_TIME_RANGES_PATH); + return rangeInputs.stream().map(CanceledTripsFilterMapper::mapTimePeriod); + }) + .toList(); + + return periods.isEmpty() ? null : periods; + } + + private static TimePeriod mapTimePeriod(Map rangeInput) { + return OffsetDateTimeRangeUtil.mapRange( + offsetDateTime(rangeInput.get("start"), RUNNING_TIME_RANGES_PATH + ".start"), + offsetDateTime(rangeInput.get("end"), RUNNING_TIME_RANGES_PATH + ".end"), + RUNNING_TIME_RANGES_PATH + ); + } + + @Nullable + private static OffsetDateTime offsetDateTime(@Nullable Object value, String path) { + if (value == null) { + return null; + } + return switch (value) { + case OffsetDateTime offsetDateTime -> offsetDateTime; + case String stringValue -> parseOffsetDateTime(stringValue, path); + default -> throw new InvalidInputException("Expected OffsetDateTime at '" + path + "'."); + }; + } + + private static OffsetDateTime parseOffsetDateTime(String value, String path) { + try { + return OffsetDateTimeParser.parseLeniently(value); + } catch (ParseException e) { + throw new InvalidInputException("Expected OffsetDateTime at '" + path + "'."); + } + } + private static TransitMode mapTransitMode(Object value) { var mode = switch (value) { case Enum enumValue -> enumValue.name(); diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/LocalDateMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/LocalDateMapper.java index 0e3e98ea5cd..7c6e30e29c0 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/LocalDateMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/LocalDateMapper.java @@ -10,6 +10,6 @@ public class LocalDateMapper { * or unbounded then {@code null} is returned. */ public static String mapToApi(LocalDate date) { - return (date == null || ServiceDateUtils.isMinMax(date)) ? null : date.toString(); + return date == null || ServiceDateUtils.isMinMax(date) ? null : date.toString(); } } diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/SeverityMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/SeverityMapper.java index ce75bd94e92..ba04628ddab 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/SeverityMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/SeverityMapper.java @@ -1,5 +1,6 @@ package org.opentripplanner.apis.gtfs.mapping; +import java.util.List; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLAlertSeverityLevelType; import org.opentripplanner.routing.alertpatch.AlertSeverity; @@ -23,4 +24,21 @@ public static GraphQLAlertSeverityLevelType getGraphQLSeverity(AlertSeverity sev case UNKNOWN_SEVERITY -> GraphQLAlertSeverityLevelType.UNKNOWN_SEVERITY; }; } + + /** + * Returns the internal {@link AlertSeverity} values that map to a GraphQL API severity level. + * Since multiple internal severities map to a single GraphQL severity, a list is returned. + */ + public static List getAlertSeverities(GraphQLAlertSeverityLevelType severity) { + return switch (severity) { + case INFO -> List.of(AlertSeverity.INFO); + case WARNING -> List.of( + AlertSeverity.VERY_SLIGHT, + AlertSeverity.SLIGHT, + AlertSeverity.WARNING + ); + case SEVERE -> List.of(AlertSeverity.VERY_SEVERE, AlertSeverity.SEVERE); + case UNKNOWN_SEVERITY -> List.of(AlertSeverity.UNKNOWN_SEVERITY); + }; + } } diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java deleted file mode 100644 index ea0238e7be8..00000000000 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.opentripplanner.apis.gtfs.mapping; - -import org.opentripplanner.core.model.i18n.NonLocalizedString; -import org.opentripplanner.core.model.id.FeedScopedId; -import org.opentripplanner.core.model.time.TimePeriod; -import org.opentripplanner.routing.alertpatch.AlertCalendar; -import org.opentripplanner.routing.alertpatch.TransitAlert; -import org.opentripplanner.routing.alertpatch.TransitAlertBuilder; -import org.opentripplanner.street.model.note.StreetNote; - -public class StreetNoteMapper { - - public static TransitAlert mapStreetNoteToAlert(StreetNote note) { - // TODO: The ID is used only in the mapping, we should instead have two mappers for the fields - TransitAlertBuilder alert = TransitAlert.of( - new FeedScopedId("StreetNote", Integer.toString(note.hashCode())) - ); - alert.withHeaderText(note.note); - alert.withDescriptionText(note.descriptionText); - alert.withUrl(NonLocalizedString.ofNullable(note.url)); - if (note.effectiveStartDate != null && note.effectiveEndDate != null) { - alert.withCalendar( - AlertCalendar.of( - TimePeriod.of(note.effectiveStartDate.toInstant(), note.effectiveEndDate.toInstant()) - ) - ); - } - return alert.build(); - } -} diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ArgumentUtils.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ArgumentUtils.java index 29734dc842a..12576013252 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ArgumentUtils.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ArgumentUtils.java @@ -58,12 +58,13 @@ static List getPlanTransitMo */ @Nullable static Map getParking(DataFetchingEnvironment environment, String type) { - return ( - (Map) ((Map) ((Map) ((Map< - String, - Object - >) environment.getArgument("preferences")).get("street")).get(type)).get("parking") - ); + return (Map) ( + (Map) ( + (Map) ((Map) environment.getArgument("preferences")).get( + "street" + ) + ).get(type) + ).get("parking"); } /** @@ -79,9 +80,10 @@ static Collection> getParkingFilters( String type ) { var parking = getParking(environment, type); - var filters = parking != null && parking.containsKey("filters") - ? getParking(environment, type).get("filters") - : null; + var filters = + parking != null && parking.containsKey("filters") + ? getParking(environment, type).get("filters") + : null; return filters != null ? (Collection>) filters : List.of(); } @@ -98,9 +100,10 @@ static Collection> getParkingPreferred( String type ) { var parking = getParking(environment, type); - var preferred = parking != null && parking.containsKey("preferred") - ? getParking(environment, type).get("preferred") - : null; + var preferred = + parking != null && parking.containsKey("preferred") + ? getParking(environment, type).get("preferred") + : null; return preferred != null ? (Collection>) preferred : List.of(); } @@ -122,11 +125,9 @@ private static Set parseFilters(Collection> filters, } private static Stream parseOperation(Collection>> map) { - return map - .stream() - .flatMap(f -> { - var tags = f.getOrDefault("tags", List.of()); - return tags.stream(); - }); + return map.stream().flatMap(f -> { + var tags = f.getOrDefault("tags", List.of()); + return tags.stream(); + }); } } diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapper.java index 75e1bd1025c..106a7d93c19 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapper.java @@ -15,7 +15,7 @@ import org.opentripplanner.api.common.LocationStringParser; import org.opentripplanner.api.parameter.QualifiedMode; import org.opentripplanner.api.parameter.QualifiedModeSet; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.framework.graphql.GraphQLUtils; @@ -38,7 +38,7 @@ public class LegacyRouteRequestMapper { public static RouteRequest toRouteRequest( DataFetchingEnvironment environment, - GraphQLRequestContext context + GtfsGraphQLRequestContext context ) { var request = context.defaultRouteRequest().copyOf(); diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapper.java index 41777b61fea..cbdaf55e52f 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapper.java @@ -12,7 +12,7 @@ import java.util.List; import java.util.Map; import javax.annotation.Nullable; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.framework.graphql.GraphQLUtils; @@ -27,7 +27,7 @@ public class RouteRequestMapper { public static RouteRequest toRouteRequest( DataFetchingEnvironment environment, - GraphQLRequestContext context + GtfsGraphQLRequestContext context ) { var request = context.defaultRouteRequest().copyOf(); var args = new GraphQLTypes.GraphQLQueryTypePlanConnectionArgs(environment.getArguments()); diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/model/CallScheduledTime.java b/application/src/main/java/org/opentripplanner/apis/gtfs/model/CallScheduledTime.java index e2e0e338173..c2dde59d25a 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/model/CallScheduledTime.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/model/CallScheduledTime.java @@ -5,7 +5,8 @@ import javax.annotation.Nullable; public sealed interface CallScheduledTime - permits CallScheduledTime.TimeWindow, CallScheduledTime.ArrivalDepartureTime { + permits CallScheduledTime.TimeWindow, CallScheduledTime.ArrivalDepartureTime +{ record ArrivalDepartureTime( @Nullable OffsetDateTime arrival, @Nullable OffsetDateTime departure diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/model/OffsetDateTimeRange.java b/application/src/main/java/org/opentripplanner/apis/gtfs/model/OffsetDateTimeRange.java new file mode 100644 index 00000000000..4ed7ced4007 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/model/OffsetDateTimeRange.java @@ -0,0 +1,46 @@ +package org.opentripplanner.apis.gtfs.model; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.Comparator; +import javax.annotation.Nullable; +import org.opentripplanner.core.model.time.TimePeriod; + +/** + * A range of time with inclusive start and exclusive end {@code [start, end)}. Both bounds are + * optional. + *

+ * A {@code null} start means that the range extends indefinitely into the past and a {@code null} + * end means that it extends indefinitely into the future. + *

+ * This is a general purpose API model which is not tied to any specific domain concept, so it can + * be used whenever an unbounded range of instants needs to be returned by the GTFS GraphQL API. + *

+ * TODO we can consider using this for use cases where the range is always required to be bounded in one or both directions. + */ +public record OffsetDateTimeRange(@Nullable OffsetDateTime start, @Nullable OffsetDateTime end) { + /** + * Orders the ranges chronologically: ranges with an unbounded start come first and ranges with an + * unbounded end come last. + */ + public static final Comparator CHRONOLOGICAL_ORDER = Comparator.comparing( + OffsetDateTimeRange::start, + Comparator.nullsFirst(Comparator.naturalOrder()) + ).thenComparing(OffsetDateTimeRange::end, Comparator.nullsLast(Comparator.naturalOrder())); + + /** + * Converts a {@link TimePeriod} into a range using the given time zone for the offsets. + */ + public static OffsetDateTimeRange of(TimePeriod period, ZoneId zoneId) { + return new OffsetDateTimeRange( + period + .start() + .map(start -> OffsetDateTime.ofInstant(start, zoneId)) + .orElse(null), + period + .end() + .map(end -> OffsetDateTime.ofInstant(end, zoneId)) + .orElse(null) + ); + } +} diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/service/ApiTransitService.java b/application/src/main/java/org/opentripplanner/apis/gtfs/service/ApiTransitService.java index 0a8da36448a..9e8ef83ed42 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/service/ApiTransitService.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/service/ApiTransitService.java @@ -8,9 +8,11 @@ import java.util.Objects; import java.util.Optional; import java.util.stream.Stream; +import javax.annotation.Nullable; import org.opentripplanner.apis.gtfs.model.StopCallOnTripOnServiceDate; import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.core.model.time.LocalDateRange; +import org.opentripplanner.core.model.time.TimePeriod; import org.opentripplanner.model.TripTimeOnDate; import org.opentripplanner.model.plan.Leg; import org.opentripplanner.transit.api.request.CancellationPolicy; @@ -95,18 +97,21 @@ public List findStopCalls(Leg leg) { /** * Find the canceled stop calls at the given stop. A call is included if either the trip it * belongs to has been canceled, or the visit at this stop has been canceled (skipped). Only calls - * whose trip's service date is within any of the given service date ranges are returned. The - * {@code arrivalDeparture} parameter controls whether drop-off-only calls are included. Each - * call is paired with the {@link TripOnServiceDate} it belongs to, which is synthesized when no - * real one exists. + * whose trip's service date is within any of the given service date ranges are returned. If + * {@code callTimePeriods} is non-null, only calls where the vehicle is scheduled to visit the + * stop during one of the periods are returned. The {@code arrivalDeparture} parameter controls + * whether drop-off-only calls are included. Each call is paired with the {@link TripOnServiceDate} + * it belongs to, which is synthesized when no real one exists. */ public List findCanceledStopCalls( StopLocation stop, List serviceDateRanges, + @Nullable List callTimePeriods, ArrivalDeparture arrivalDeparture ) { var request = TripTimeOnDateRequest.of(List.of(stop)) .withServiceDateRanges(serviceDateRanges) + .withIncludeCallTimePeriods(callTimePeriods) .withArrivalDeparture(arrivalDeparture) .withNumberOfDepartures(Integer.MAX_VALUE) .withCancellationPolicy(CancellationPolicy.ONLY_CANCELLATIONS) diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/support/filter/AlertsFilter.java b/application/src/main/java/org/opentripplanner/apis/gtfs/support/filter/AlertsFilter.java new file mode 100644 index 00000000000..ad151acc17a --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/support/filter/AlertsFilter.java @@ -0,0 +1,56 @@ +package org.opentripplanner.apis.gtfs.support.filter; + +import static org.opentripplanner.apis.gtfs.mapping.AlertCauseMapper.getGraphQLCause; +import static org.opentripplanner.apis.gtfs.mapping.AlertEffectMapper.getGraphQLEffect; +import static org.opentripplanner.apis.gtfs.mapping.SeverityMapper.getGraphQLSeverity; + +import java.util.Collection; +import java.util.List; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.routing.alertpatch.EntitySelector; +import org.opentripplanner.routing.alertpatch.TransitAlert; + +public class AlertsFilter { + + public static List filterAlerts( + Collection alerts, + GraphQLTypes.GraphQLQueryTypeAlertsArgs args + ) { + var severities = args.getGraphQLSeverityLevel(); + var effects = args.getGraphQLEffect(); + var causes = args.getGraphQLCause(); + return alerts + .stream() + .filter( + alert -> + args.getGraphQLFeeds() == null || + args.getGraphQLFeeds().contains(alert.getId().getFeedId()) + ) + .filter( + alert -> severities == null || severities.contains(getGraphQLSeverity(alert.severity())) + ) + .filter(alert -> effects == null || effects.contains(getGraphQLEffect(alert.effect()))) + .filter(alert -> causes == null || causes.contains(getGraphQLCause(alert.cause()))) + .filter( + alert -> + args.getGraphQLRoute() == null || + alert + .entities() + .stream() + .filter(entitySelector -> entitySelector instanceof EntitySelector.Route) + .map(EntitySelector.Route.class::cast) + .anyMatch(route -> args.getGraphQLRoute().contains(route.routeId().toString())) + ) + .filter( + alert -> + args.getGraphQLStop() == null || + alert + .entities() + .stream() + .filter(entitySelector -> entitySelector instanceof EntitySelector.Stop) + .map(EntitySelector.Stop.class::cast) + .anyMatch(stop -> args.getGraphQLStop().contains(stop.stopId().toString())) + ) + .toList(); + } +} diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/support/filter/StopArrivalByTypeFilter.java b/application/src/main/java/org/opentripplanner/apis/gtfs/support/filter/StopArrivalByTypeFilter.java index 6c4687cd98c..4d83fed1c9b 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/support/filter/StopArrivalByTypeFilter.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/support/filter/StopArrivalByTypeFilter.java @@ -46,12 +46,13 @@ private static Set map(@Nullable Collection - switch (type) { - case LOCATION -> StopType.FLEXIBLE_AREA; - case LOCATION_GROUP -> StopType.FLEXIBLE_GROUP; - case STOP -> StopType.REGULAR; - } + .map( + type -> + switch (type) { + case LOCATION -> StopType.FLEXIBLE_AREA; + case LOCATION_GROUP -> StopType.FLEXIBLE_GROUP; + case STOP -> StopType.REGULAR; + } ) .collect(Collectors.toSet()); return EnumSetUtils.unmodifiableEnumSet(allowed, StopType.class); diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/support/sort/AlertsConnectionOrdering.java b/application/src/main/java/org/opentripplanner/apis/gtfs/support/sort/AlertsConnectionOrdering.java new file mode 100644 index 00000000000..4ac711e876f --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/support/sort/AlertsConnectionOrdering.java @@ -0,0 +1,53 @@ +package org.opentripplanner.apis.gtfs.support.sort; + +import java.time.Instant; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import org.opentripplanner.routing.alertpatch.AlertSeverity; +import org.opentripplanner.routing.alertpatch.TransitAlert; + +/** + * Defines the ordering of the alerts returned by the GraphQL {@code alertsConnection} field. + * Note, this ordering is not set in stone and can be changed/removed if need be. + *

+ * The order is fixed, deterministic and not configurable through the API: + *

    + *
  1. {@link AlertSeverity} descending, using {@link AlertSeverity#sortingIndex()}, so the most + * severe alerts come first. An alert without a severity is treated as + * {@link AlertSeverity#UNKNOWN_SEVERITY}.
  2. + *
  3. Within the same severity, the effective start of the alert's validity + * ({@link TransitAlert#getEffectiveStartDate()}) ascending. Alerts with an open start (or which + * are never active) have no effective start and come first.
  4. + *
  5. The alert id ascending. This is a pure tiebreaker which makes the order stable, so that + * paging through the connection never skips or duplicates an alert.
  6. + *
+ * The connection uses index based cursors, so the ordering only needs to be applied to the + * complete list before the connection is built. + */ +public class AlertsConnectionOrdering { + + private static final Comparator BY_EFFECTIVE_START = Comparator.nullsFirst( + Comparator.naturalOrder() + ); + + private static final Comparator COMPARATOR = Comparator.comparingInt( + (TransitAlert alert) -> severity(alert).sortingIndex() + ) + .reversed() + .thenComparing(TransitAlert::getEffectiveStartDate, BY_EFFECTIVE_START) + .thenComparing(TransitAlert::getId); + + /** + * Returns a new list containing the given alerts in the order described in + * {@link AlertsConnectionOrdering}. + */ + public static List sort(Collection alerts) { + return alerts.stream().sorted(COMPARATOR).toList(); + } + + private static AlertSeverity severity(TransitAlert alert) { + var severity = alert.severity(); + return severity == null ? AlertSeverity.UNKNOWN_SEVERITY : severity; + } +} diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/support/time/OffsetDateTimeRangeUtil.java b/application/src/main/java/org/opentripplanner/apis/gtfs/support/time/OffsetDateTimeRangeUtil.java new file mode 100644 index 00000000000..ac586f70f72 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/support/time/OffsetDateTimeRangeUtil.java @@ -0,0 +1,68 @@ +package org.opentripplanner.apis.gtfs.support.time; + +import java.time.OffsetDateTime; +import java.util.List; +import javax.annotation.Nullable; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.apis.support.InvalidInputException; +import org.opentripplanner.core.model.time.TimePeriod; + +/** + * Utilities for mapping the GraphQL {@code OffsetDateTimeRangeInput} to the domain type + * {@link TimePeriod}. + */ +public class OffsetDateTimeRangeUtil { + + /** + * Maps a list of GraphQL time range inputs to {@link TimePeriod}s. Returns {@code null} when the + * input is {@code null}. An empty list throws an exception. + */ + @Nullable + public static List mapRanges( + @Nullable List ranges, + String fieldName + ) { + if (ranges == null) { + return null; + } + requireNonEmpty(ranges, fieldName); + return ranges + .stream() + .map(range -> mapRange(range.getGraphQLStart(), range.getGraphQLEnd(), fieldName)) + .toList(); + } + + /** + * Maps a single GraphQL time range to a {@link TimePeriod}. The start is inclusive and the end + * exclusive and both of them are optional. + */ + public static TimePeriod mapRange( + @Nullable OffsetDateTime start, + @Nullable OffsetDateTime end, + String fieldName + ) { + try { + return TimePeriod.of( + start == null ? null : start.toInstant(), + end == null ? null : end.toInstant() + ); + } catch (IllegalArgumentException e) { + throw new InvalidInputException( + "The start of the time range '%s' must not be after its end.".formatted(fieldName) + ); + } + } + + /** + * Throws an exception if the given list of ranges is empty as an empty filter is ambiguous. + */ + public static void requireNonEmpty(List ranges, String fieldName) { + if (ranges.isEmpty()) { + throw new InvalidInputException( + "Time range filter '%s' must be either null or have at least one entry.".formatted( + fieldName + ) + ); + } + } +} diff --git a/application/src/main/java/org/opentripplanner/apis/support/graphql/injectdoc/ApiDocumentationProfile.java b/application/src/main/java/org/opentripplanner/apis/support/graphql/injectdoc/ApiDocumentationProfile.java index 3f2e693c6dd..b4160555927 100644 --- a/application/src/main/java/org/opentripplanner/apis/support/graphql/injectdoc/ApiDocumentationProfile.java +++ b/application/src/main/java/org/opentripplanner/apis/support/graphql/injectdoc/ApiDocumentationProfile.java @@ -7,11 +7,11 @@ public enum ApiDocumentationProfile implements DocumentedEnum "Default documentation is used."; case ENTUR -> "Entur specific documentation. This deprecate features not supported at Entur," + - " Norway."; + " Norway."; }; } } diff --git a/application/src/main/java/org/opentripplanner/apis/support/graphql/injectdoc/InjectCustomDocumentation.java b/application/src/main/java/org/opentripplanner/apis/support/graphql/injectdoc/InjectCustomDocumentation.java index 4e98f202d90..0c3f59fb2d9 100644 --- a/application/src/main/java/org/opentripplanner/apis/support/graphql/injectdoc/InjectCustomDocumentation.java +++ b/application/src/main/java/org/opentripplanner/apis/support/graphql/injectdoc/InjectCustomDocumentation.java @@ -25,7 +25,8 @@ */ public class InjectCustomDocumentation extends GraphQLTypeVisitorStub - implements GraphQLTypeVisitor { + implements GraphQLTypeVisitor +{ private final CustomDocumentation customDocumentation; diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java index 8dd4f43a655..5ec506424fa 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java @@ -20,7 +20,6 @@ import java.util.HashMap; import java.util.Map; import org.opentripplanner.apis.support.TracingUtils; -import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,11 +29,11 @@ public class TransmodelAPI { // Note, the blank line at the end is intended private static final String SCHEMA_DOC_HEADER = """ - # THIS IS NOT INTENDED FOR PRODUCTION USE. We recommend using the GraphQL introspection instead. - # This is intended for the OTP Debug UI and can also be used by humans to get the schema with the - # OTP configured default-values injected. + # THIS IS NOT INTENDED FOR PRODUCTION USE. We recommend using the GraphQL introspection instead. + # This is intended for the OTP Debug UI and can also be used by humans to get the schema with the + # OTP configured default-values injected. - """; + """; private static final Logger LOG = LoggerFactory.getLogger(TransmodelAPI.class); @@ -76,7 +75,7 @@ public TransmodelAPIOldPath( public Response getGraphQL( HashMap queryParameters, @Context HttpHeaders headers, - @Context OtpServerRequestContext serverContext + @Context TransmodelRequestContext requestContext ) { if (queryParameters == null || !queryParameters.containsKey("query")) { LOG.debug("No query found in body"); @@ -105,7 +104,7 @@ public Response getGraphQL( String operationName = (String) queryParameters.getOrDefault("operationName", null); return index.executeGraphQL( query, - serverContext, + requestContext, variables, operationName, maxNumberOfResultFields, @@ -118,11 +117,11 @@ public Response getGraphQL( public Response getGraphQL( String query, @Context HttpHeaders headers, - @Context OtpServerRequestContext serverContext + @Context TransmodelRequestContext requestContext ) { return index.executeGraphQL( query, - serverContext, + requestContext, null, null, maxNumberOfResultFields, diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraph.java b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraph.java index 0d1882ab093..8bee917a311 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraph.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraph.java @@ -23,7 +23,6 @@ import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.application.OTPRequestTimeoutException; import org.opentripplanner.framework.concurrent.OtpRequestThreadFactory; -import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.transit.model.framework.EntityNotFoundException; import org.opentripplanner.utils.lang.ObjectUtils; import org.slf4j.Logger; @@ -45,7 +44,7 @@ class TransmodelGraph { Response executeGraphQL( String query, - OtpServerRequestContext serverContext, + TransmodelRequestContext transmodelRequestContext, Map variables, String operationName, int maxNumberOfResultFields, @@ -54,10 +53,8 @@ Response executeGraphQL( try (var executionStrategy = new AbortOnUnprocessableRequestExecutionStrategy()) { variables = ObjectUtils.ifNotNull(variables, new HashMap<>()); var instrumentation = createInstrumentation(maxNumberOfResultFields, tracingTags); - var transmodelRequestContext = createRequestContext(serverContext); var executionInput = createExecutionInput( query, - serverContext, variables, operationName, transmodelRequestContext @@ -95,20 +92,8 @@ private static Instrumentation createInstrumentation( return instrumentation; } - private static TransmodelRequestContext createRequestContext( - OtpServerRequestContext serverContext - ) { - return new TransmodelRequestContext( - serverContext, - serverContext.routingService(), - serverContext.transitService(), - serverContext.empiricalDelayService() - ); - } - private static ExecutionInput createExecutionInput( String query, - OtpServerRequestContext serverContext, Map variables, String operationName, TransmodelRequestContext transmodelRequestContext @@ -117,7 +102,6 @@ private static ExecutionInput createExecutionInput( .query(query) .operationName(operationName) .context(transmodelRequestContext) - .root(serverContext) .variables(variables) .build(); } diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLPlanner.java b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLPlanner.java index 65f3ce8f685..027f28127a8 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLPlanner.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLPlanner.java @@ -84,6 +84,6 @@ public DataFetcherResult planVia(DataFetchingEnvironment env } private static Locale defaultLocale(TransmodelRequestContext ctx) { - return ctx.getServerContext().defaultRouteRequest().preferences().locale(); + return ctx.getDefaultRouteRequest().preferences().locale(); } } diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchemaFactory.java b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchemaFactory.java index 09bfc5ebf15..5ecc6c4269f 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchemaFactory.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchemaFactory.java @@ -941,13 +941,12 @@ private GraphQLSchema createDefault() { @SuppressWarnings("rawtypes") Map filterByIds = environment.getArgument("filterByIds"); if (filterByIds != null) { - filterByStops = idMapper.parseListNullSafe(((List) filterByIds.get("quays"))); - filterByRoutes = idMapper.parseListNullSafe( - ((List) filterByIds.get("lines")) - ); - filterByBikeRentalStations = filterByIds.get("bikeRentalStations") != null - ? (List) filterByIds.get("bikeRentalStations") - : List.of(); + filterByStops = idMapper.parseListNullSafe((List) filterByIds.get("quays")); + filterByRoutes = idMapper.parseListNullSafe((List) filterByIds.get("lines")); + filterByBikeRentalStations = + filterByIds.get("bikeRentalStations") != null + ? (List) filterByIds.get("bikeRentalStations") + : List.of(); } List filterByTransportModes = environment.getArgument("filterByModes"); @@ -1476,7 +1475,7 @@ private GraphQLSchema createDefault() { } if (environment.getArgument("codespaces") instanceof List) { - codespaces.addAll((environment.getArgument("codespaces"))); + codespaces.addAll(environment.getArgument("codespaces")); } if (!codespaces.isEmpty()) { diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelRequestContext.java b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelRequestContext.java index f43bbca6ad8..d6650aea51c 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelRequestContext.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelRequestContext.java @@ -2,33 +2,65 @@ import javax.annotation.Nullable; import org.opentripplanner.ext.empiricaldelay.EmpiricalDelayService; +import org.opentripplanner.place.NearbyPlaceFinder; +import org.opentripplanner.place.NearbyStopFinder; +import org.opentripplanner.place.nearbystopfinder.StraightLineNearbyStopFinder; +import org.opentripplanner.place.nearbystopfinder.StreetNearbyStopFinder; +import org.opentripplanner.place.placefinder.StreetNearbyPlaceFinder; import org.opentripplanner.routing.api.RoutingService; +import org.opentripplanner.routing.api.request.RouteRequest; +import org.opentripplanner.routing.linking.LinkingContextFactory; import org.opentripplanner.routing.services.TransitAlertService; -import org.opentripplanner.standalone.api.OtpServerRequestContext; +import org.opentripplanner.service.streetdetails.StreetDetailsService; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; +import org.opentripplanner.service.vehiclerental.VehicleRentalService; +import org.opentripplanner.street.graph.Graph; +import org.opentripplanner.street.service.StreetLimitationParametersService; +import org.opentripplanner.transfer.regular.RegularTransferService; import org.opentripplanner.transit.service.TransitService; import org.opentripplanner.utils.lang.Sandbox; public class TransmodelRequestContext { - private final OtpServerRequestContext serverContext; private final RoutingService routingService; private final TransitService transitService; + private final TransitAlertService transitAlertService; private final @Nullable EmpiricalDelayService empiricalDelayService; + private final RouteRequest defaultRouteRequest; + private final VehicleRentalService vehicleRentalService; + private final VehicleParkingService vehicleParkingService; + private final Graph graph; + private final RegularTransferService transferService; + private final StreetDetailsService streetDetailsService; + private final LinkingContextFactory linkingContextFactory; + private final StreetLimitationParametersService streetLimitationParametersService; public TransmodelRequestContext( - OtpServerRequestContext serverContext, RoutingService routingService, TransitService transitService, - EmpiricalDelayService empiricalDelayService + TransitAlertService transitAlertService, + @Nullable EmpiricalDelayService empiricalDelayService, + RouteRequest defaultRouteRequest, + VehicleRentalService vehicleRentalService, + VehicleParkingService vehicleParkingService, + Graph graph, + RegularTransferService transferService, + StreetDetailsService streetDetailsService, + LinkingContextFactory linkingContextFactory, + StreetLimitationParametersService streetLimitationParametersService ) { - this.serverContext = serverContext; this.routingService = routingService; this.transitService = transitService; + this.transitAlertService = transitAlertService; this.empiricalDelayService = empiricalDelayService; - } - - public OtpServerRequestContext getServerContext() { - return serverContext; + this.defaultRouteRequest = defaultRouteRequest; + this.vehicleRentalService = vehicleRentalService; + this.vehicleParkingService = vehicleParkingService; + this.graph = graph; + this.transferService = transferService; + this.streetDetailsService = streetDetailsService; + this.linkingContextFactory = linkingContextFactory; + this.streetLimitationParametersService = streetLimitationParametersService; } public RoutingService getRoutingService() { @@ -40,7 +72,7 @@ public TransitService getTransitService() { } public TransitAlertService getTransitAlertService() { - return serverContext.transitAlertService(); + return transitAlertService; } @Nullable @@ -48,4 +80,46 @@ public TransitAlertService getTransitAlertService() { public EmpiricalDelayService getEmpiricalDelayService() { return empiricalDelayService; } + + public RouteRequest getDefaultRouteRequest() { + return defaultRouteRequest; + } + + public VehicleRentalService getVehicleRentalService() { + return vehicleRentalService; + } + + public VehicleParkingService getVehicleParkingService() { + return vehicleParkingService; + } + + public Graph getGraph() { + return graph; + } + + public RegularTransferService getTransferService() { + return transferService; + } + + public StreetDetailsService getStreetDetailsService() { + return streetDetailsService; + } + + public LinkingContextFactory getLinkingContextFactory() { + return linkingContextFactory; + } + + public StreetLimitationParametersService getStreetLimitationParametersService() { + return streetLimitationParametersService; + } + + public NearbyPlaceFinder getNearbyPlaceFinder() { + return new StreetNearbyPlaceFinder(linkingContextFactory); + } + + public NearbyStopFinder getNearbyStopFinder() { + return graph.hasStreets + ? StreetNearbyStopFinder.of(linkingContextFactory).build() + : new StraightLineNearbyStopFinder(transitService::findRegularStopsByBoundingBox); + } } diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TransitFilterOldWayMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TransitFilterOldWayMapper.java index a33d0d712c1..51908daab97 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TransitFilterOldWayMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TransitFilterOldWayMapper.java @@ -31,8 +31,10 @@ void mapFilter( TransitRequestBuilder transitBuilder ) { if ( - !(GqlUtil.hasArgument(environment, "modes") && - ((Map) environment.getArgument("modes")).containsKey("transportModes")) && + !( + GqlUtil.hasArgument(environment, "modes") && + ((Map) environment.getArgument("modes")).containsKey("transportModes") + ) && !GqlUtil.hasArgument(environment, "whiteListed") && !GqlUtil.hasArgument(environment, "banned") ) { diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapper.java index 0f82395c74e..cbea7905bab 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapper.java @@ -42,8 +42,7 @@ public RouteRequest createRequest(DataFetchingEnvironment dataFetchingEnvironmen */ public RouteRequestBuilder createRequestBuilder(DataFetchingEnvironment environment) { TransmodelRequestContext context = environment.getContext(); - var serverContext = context.getServerContext(); - var requestBuilder = serverContext.defaultRouteRequest().copyOf(); + var requestBuilder = context.getDefaultRouteRequest().copyOf(); DataFetcherDecorator callWith = new DataFetcherDecorator(environment); diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaRequestMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaRequestMapper.java index 8d9b52b8703..d7dd24881bf 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaRequestMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaRequestMapper.java @@ -12,7 +12,6 @@ import org.opentripplanner.routing.api.request.RouteViaRequest; import org.opentripplanner.routing.api.request.ViaLocationDeprecated; import org.opentripplanner.routing.api.request.request.JourneyRequest; -import org.opentripplanner.standalone.api.OtpServerRequestContext; /** * This class maps a GraphQL viaTrip query into a {@link RouteViaRequest} @@ -34,8 +33,7 @@ public ViaRequestMapper(FeedScopedIdMapper idMapper) { */ public RouteViaRequest createRouteViaRequest(DataFetchingEnvironment environment) { TransmodelRequestContext context = environment.getContext(); - OtpServerRequestContext serverContext = context.getServerContext(); - RouteRequest request = serverContext.defaultRouteRequest(); + RouteRequest request = context.getDefaultRouteRequest(); List> viaInput = environment.getArgument("via"); List vias = viaInput diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java index 1b5b1debda3..26b3db902d2 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java @@ -497,6 +497,7 @@ public class EnumTypes { .value("trolleybus", TransitMode.TROLLEYBUS) .value("monorail", TransitMode.MONORAIL) .value("coach", TransitMode.COACH) + .value("carpool", TransitMode.CARPOOL) .value("unknown", "unknown") .build(); @@ -506,14 +507,15 @@ public class EnumTypes { TransmodelTransportSubmode::getValue ); - public static final GraphQLEnumType VERTEX_TYPE = GraphQLEnumType.newEnum() - .name("VertexType") - .value("normal", VertexType.NORMAL) - .value("transit", VertexType.TRANSIT) - .value("bikePark", VertexType.VEHICLEPARKING) - .value("bikeShare", VertexType.VEHICLERENTAL) - //TODO QL: .value("parkAndRide", VertexType.PARKANDRIDE) - .build(); + public static final GraphQLEnumType VERTEX_TYPE = + GraphQLEnumType.newEnum() + .name("VertexType") + .value("normal", VertexType.NORMAL) + .value("transit", VertexType.TRANSIT) + .value("bikePark", VertexType.VEHICLEPARKING) + .value("bikeShare", VertexType.VEHICLERENTAL) + //TODO QL: .value("parkAndRide", VertexType.PARKANDRIDE) + .build(); public static final GraphQLEnumType VIA_LOCATION_TYPE = GraphQLEnumType.newEnum() .name("ViaLocationType") diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ValidityPeriodType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ValidityPeriodType.java index ca027e0da99..70e910703b0 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ValidityPeriodType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ValidityPeriodType.java @@ -14,7 +14,9 @@ public static GraphQLObjectType create(GraphQLScalarType dateTimeScalar) { GraphQLFieldDefinition.newFieldDefinition() .name("startTime") .type(dateTimeScalar) - .description("Start of validity period") + .description( + "The inclusive start of the validity period. Will return 'null' if the validity has an unbounded start." + ) .dataFetcher(environment -> { ValidityPeriod period = environment.getSource(); return period != null ? period.startTime() : null; @@ -25,7 +27,9 @@ public static GraphQLObjectType create(GraphQLScalarType dateTimeScalar) { GraphQLFieldDefinition.newFieldDefinition() .name("endTime") .type(dateTimeScalar) - .description("End of validity period. Will return 'null' if validity is open-ended.") + .description( + "The exclusive end of the validity period. Will return 'null' if the validity has an unbounded end." + ) .dataFetcher(environment -> { ValidityPeriod period = environment.getSource(); return period != null ? period.endTime() : null; diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/JourneyPatternType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/JourneyPatternType.java index 3295d9b07ac..031ca8e083b 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/JourneyPatternType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/JourneyPatternType.java @@ -94,7 +94,8 @@ public GraphQLObjectType create( ) ); - return ((TripPattern) environment.getSource()).getScheduledTimetable() + return ((TripPattern) environment.getSource()) + .getScheduledTimetable() .getTripTimes() .stream() .filter(times -> services.contains(times.getServiceCode())) diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/LineType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/LineType.java index df594a27f35..e11314b2fce 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/LineType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/LineType.java @@ -64,21 +64,21 @@ public GraphQLObjectType create( GraphQLFieldDefinition.newFieldDefinition() .name("authority") .type(authorityType) - .dataFetcher(environment -> (getSource(environment).getAgency())) + .dataFetcher(environment -> getSource(environment).getAgency()) .build() ) .field( GraphQLFieldDefinition.newFieldDefinition() .name("operator") .type(operatorType) - .dataFetcher(environment -> ((getSource(environment)).getOperator())) + .dataFetcher(environment -> getSource(environment).getOperator()) .build() ) .field( GraphQLFieldDefinition.newFieldDefinition() .name("branding") .type(brandingType) - .dataFetcher(environment -> (getSource(environment)).getBranding()) + .dataFetcher(environment -> getSource(environment).getBranding()) ) .field( GraphQLFieldDefinition.newFieldDefinition() @@ -87,21 +87,21 @@ public GraphQLObjectType create( .description( "Publicly announced code for line, differentiating it from other lines for the same operator." ) - .dataFetcher(environment -> ((getSource(environment)).getShortName())) + .dataFetcher(environment -> getSource(environment).getShortName()) .build() ) .field( GraphQLFieldDefinition.newFieldDefinition() .name("name") .type(Scalars.GraphQLString) - .dataFetcher(environment -> (getSource(environment)).getLongName()) + .dataFetcher(environment -> getSource(environment).getLongName()) .build() ) .field( GraphQLFieldDefinition.newFieldDefinition() .name("transportMode") .type(EnumTypes.TRANSPORT_MODE) - .dataFetcher(environment -> (getSource(environment)).getMode()) + .dataFetcher(environment -> getSource(environment).getMode()) .build() ) .field( @@ -109,7 +109,7 @@ public GraphQLObjectType create( .name("transportSubmode") .type(EnumTypes.TRANSPORT_SUBMODE) .dataFetcher(environment -> - TransmodelTransportSubmode.fromValue((getSource(environment)).getNetexSubmode()) + TransmodelTransportSubmode.fromValue(getSource(environment).getNetexSubmode()) ) .build() ) @@ -117,7 +117,7 @@ public GraphQLObjectType create( GraphQLFieldDefinition.newFieldDefinition() .name("description") .type(Scalars.GraphQLString) - .dataFetcher(environment -> (getSource(environment)).getDescription()) + .dataFetcher(environment -> getSource(environment).getDescription()) .build() ) .field( @@ -191,7 +191,7 @@ public GraphQLObjectType create( .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(ptSituationElementType)))) .dataFetcher(environment -> GqlUtil.getTransitAlertService(environment).getRouteAlerts( - (getSource(environment)).getId() + getSource(environment).getId() ) ) .build() @@ -201,7 +201,7 @@ public GraphQLObjectType create( .name("flexibleLineType") .description("Type of flexible line, or null if line is not flexible.") .type(Scalars.GraphQLString) - .dataFetcher(environment -> (getSource(environment)).getFlexibleLineType()) + .dataFetcher(environment -> getSource(environment).getFlexibleLineType()) .build() ) .field( @@ -220,7 +220,7 @@ public GraphQLObjectType create( .name("groupOfLines") .description("Groups of lines that line is a part of.") .type(new GraphQLNonNull(new GraphQLList(groupOfLinesType))) - .dataFetcher(environment -> (getSource(environment)).getGroupsOfRoutes()) + .dataFetcher(environment -> getSource(environment).getGroupsOfRoutes()) .build() ) .field( diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ElevationProfileStepType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ElevationProfileStepType.java index 841df61631a..5d921237264 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ElevationProfileStepType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ElevationProfileStepType.java @@ -19,7 +19,8 @@ static String makeDescription(String name) { The %s's elevation profile. All elevation values, including the first one, are in meters above sea level. The elevation is negative for places below sea level. The profile includes both the start and end coordinate. - """.formatted(name) + """ + .formatted(name) .stripIndent(); } diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/LegType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/LegType.java index f1e77f7a03c..b054cd8f52c 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/LegType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/LegType.java @@ -84,8 +84,10 @@ public static GraphQLObjectType create( .description("The aimed date and time this leg starts.") .type(new GraphQLNonNull(dateTimeScalar)) .dataFetcher(env -> - // startTime is already adjusted for real-time - need to subtract delay to get aimed time - leg(env).startTime().minusSeconds(leg(env).departureDelay()) + leg(env) + .startTime() + // startTime is already adjusted for real-time - need to subtract delay to get aimed time + .minusSeconds(leg(env).departureDelay()) ) .build() ) @@ -298,7 +300,9 @@ public static GraphQLObjectType create( ) .type(TransmodelScalars.DATE_SCALAR) .dataFetcher(environment -> - Optional.of((Leg) environment.getSource()).map(Leg::serviceDate).orElse(null) + Optional.of((Leg) environment.getSource()) + .map(Leg::serviceDate) + .orElse(null) ) .build() ) @@ -314,13 +318,11 @@ public static GraphQLObjectType create( if (stops == null || stops.isEmpty()) { return List.of(); } else { - return ( - stops - .stream() - .map(stop -> stop.place.stop) - .filter(Objects::nonNull) - .collect(Collectors.toList()) - ); + return stops + .stream() + .map(stop -> stop.place.stop) + .filter(Objects::nonNull) + .collect(Collectors.toList()); } }) .build() diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java index 74d67a8d080..60a96732212 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java @@ -13,131 +13,135 @@ public class PathGuidanceType { public static GraphQLObjectType create(GraphQLObjectType elevationStepType) { - return GraphQLObjectType.newObject() - .name("PathGuidance") - .description("A series of turn by turn instructions used for walking, biking and driving.") - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("distance") - .description("The distance in meters that this step takes.") - .type(Scalars.GraphQLFloat) - .dataFetcher(environment -> ((WalkStep) environment.getSource()).getDistance()) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("relativeDirection") - .description("The relative direction of this step.") - .type(EnumTypes.RELATIVE_DIRECTION) - .dataFetcher(environment -> - RelativeDirectionMapper.map(((WalkStep) environment.getSource()).getRelativeDirection()) - ) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("streetName") - .description("The name of the street.") - .type(Scalars.GraphQLString) - .dataFetcher(environment -> - GraphQLUtils.getTranslation( - ((WalkStep) environment.getSource()).getDirectionText(), - environment + return ( + GraphQLObjectType.newObject() + .name("PathGuidance") + .description("A series of turn by turn instructions used for walking, biking and driving.") + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("distance") + .description("The distance in meters that this step takes.") + .type(Scalars.GraphQLFloat) + .dataFetcher(environment -> ((WalkStep) environment.getSource()).getDistance()) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("relativeDirection") + .description("The relative direction of this step.") + .type(EnumTypes.RELATIVE_DIRECTION) + .dataFetcher(environment -> + RelativeDirectionMapper.map( + ((WalkStep) environment.getSource()).getRelativeDirection() + ) ) - ) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("heading") - .description("The absolute direction of this step.") - .type(EnumTypes.ABSOLUTE_DIRECTION) - .dataFetcher(environment -> - ((WalkStep) environment.getSource()).getAbsoluteDirection().orElse(null) - ) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("exit") - .description("When exiting a highway or traffic circle, the exit name/number.") - .type(Scalars.GraphQLString) - .dataFetcher(environment -> - ((WalkStep) environment.getSource()).highwayExit().orElse(null) - ) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("stayOn") - .description("Indicates whether or not a street changes direction at an intersection.") - .type(Scalars.GraphQLBoolean) - .dataFetcher(environment -> ((WalkStep) environment.getSource()).isStayOn()) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("area") - .description( - "This step is on an open area, such as a plaza or train platform, and thus the directions should say something like \"cross\"" - ) - .type(Scalars.GraphQLBoolean) - .dataFetcher(environment -> ((WalkStep) environment.getSource()).getArea()) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("bogusName") - .description( - "The name of this street was generated by the system, so we should only display it once, and generally just display right/left directions" - ) - .type(Scalars.GraphQLBoolean) - .dataFetcher(environment -> ((WalkStep) environment.getSource()).nameIsDerived()) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("latitude") - .description("The latitude of the step.") - .type(Scalars.GraphQLFloat) - .dataFetcher(environment -> - ((WalkStep) environment.getSource()).getStartLocation().latitude() - ) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("longitude") - .description("The longitude of the step.") - .type(Scalars.GraphQLFloat) - .dataFetcher(environment -> - ((WalkStep) environment.getSource()).getStartLocation().longitude() - ) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("elevationProfile") - .description(ElevationProfileStepType.makeDescription("step")) - .type(new GraphQLNonNull(new GraphQLList(elevationStepType))) - .dataFetcher(environment -> - ElevationProfileStepType.mapElevationProfile( - ((WalkStep) environment.getSource()).getElevationProfile() + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("streetName") + .description("The name of the street.") + .type(Scalars.GraphQLString) + .dataFetcher(environment -> + GraphQLUtils.getTranslation( + ((WalkStep) environment.getSource()).getDirectionText(), + environment + ) ) - ) - .build() - ) - // .field(GraphQLFieldDefinition.newFieldDefinition() - // .name("legStepText") - // .description("Direction information as readable text.") - // .type(Scalars.GraphQLString) - // .argument(GraphQLArgument.newArgument() - // .name("locale") - // .type(localeEnum) - // .defaultValue("no") - // .build()) - // .dataFetcher(environment -> ((WalkStep) environment.getSource()).getLegStepText(environment)) - // .build()) - .build(); + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("heading") + .description("The absolute direction of this step.") + .type(EnumTypes.ABSOLUTE_DIRECTION) + .dataFetcher(environment -> + ((WalkStep) environment.getSource()).getAbsoluteDirection().orElse(null) + ) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("exit") + .description("When exiting a highway or traffic circle, the exit name/number.") + .type(Scalars.GraphQLString) + .dataFetcher(environment -> + ((WalkStep) environment.getSource()).highwayExit().orElse(null) + ) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("stayOn") + .description("Indicates whether or not a street changes direction at an intersection.") + .type(Scalars.GraphQLBoolean) + .dataFetcher(environment -> ((WalkStep) environment.getSource()).isStayOn()) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("area") + .description( + "This step is on an open area, such as a plaza or train platform, and thus the directions should say something like \"cross\"" + ) + .type(Scalars.GraphQLBoolean) + .dataFetcher(environment -> ((WalkStep) environment.getSource()).getArea()) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("bogusName") + .description( + "The name of this street was generated by the system, so we should only display it once, and generally just display right/left directions" + ) + .type(Scalars.GraphQLBoolean) + .dataFetcher(environment -> ((WalkStep) environment.getSource()).nameIsDerived()) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("latitude") + .description("The latitude of the step.") + .type(Scalars.GraphQLFloat) + .dataFetcher(environment -> + ((WalkStep) environment.getSource()).getStartLocation().latitude() + ) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("longitude") + .description("The longitude of the step.") + .type(Scalars.GraphQLFloat) + .dataFetcher(environment -> + ((WalkStep) environment.getSource()).getStartLocation().longitude() + ) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("elevationProfile") + .description(ElevationProfileStepType.makeDescription("step")) + .type(new GraphQLNonNull(new GraphQLList(elevationStepType))) + .dataFetcher(environment -> + ElevationProfileStepType.mapElevationProfile( + ((WalkStep) environment.getSource()).getElevationProfile() + ) + ) + .build() + ) + // .field(GraphQLFieldDefinition.newFieldDefinition() + // .name("legStepText") + // .description("Direction information as readable text.") + // .type(Scalars.GraphQLString) + // .argument(GraphQLArgument.newArgument() + // .name("locale") + // .type(localeEnum) + // .defaultValue("no") + // .build()) + // .dataFetcher(environment -> ((WalkStep) environment.getSource()).getLegStepText(environment)) + // .build()) + .build() + ); } } diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PlanPlaceType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PlanPlaceType.java index de3ef34449e..8dc8ac1e32b 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PlanPlaceType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PlanPlaceType.java @@ -22,152 +22,154 @@ public static GraphQLObjectType create( GraphQLOutputType rentalVehicleType, GraphQLOutputType quayType ) { - return GraphQLObjectType.newObject() - .name("Place") - .description( - "Common super class for all places (stop places, quays, car parks, bike parks and bike rental stations )" - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("name") - .description( - "For transit quays, the name of the quay. For points of interest, the name of the POI." - ) - .type(Scalars.GraphQLString) - .dataFetcher(environment -> - GraphQLUtils.getTranslation(((Place) environment.getSource()).name, environment) - ) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("vertexType") - .description( - "Type of vertex. (Normal, Bike sharing station, Bike P+R, Transit quay) Mostly used for better localization of bike sharing and P+R station names" - ) - .type(EnumTypes.VERTEX_TYPE) - .dataFetcher(environment -> ((Place) environment.getSource()).vertexType) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("latitude") - .description("The latitude of the place.") - .type(new GraphQLNonNull(Scalars.GraphQLFloat)) - .dataFetcher(environment -> { - var coordinate = ((Place) environment.getSource()).coordinate; - if (coordinate == null) { - // TODO: Technically this is wrong, we should not return the place the user sends to - // us, as that is the only place the value can be null - return 0; - } - return coordinate.latitude(); - }) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("longitude") - .description("The longitude of the place.") - .type(new GraphQLNonNull(Scalars.GraphQLFloat)) - .dataFetcher(environment -> { - var coordinate = ((Place) environment.getSource()).coordinate; - if (coordinate == null) { - // TODO: Technically this is wrong, we should not return the place the user sends to - // us, as that is the only place the value can be null - return 0; - } - return coordinate.longitude(); - }) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("quay") - .description("The quay related to the place.") - .type(quayType) - .dataFetcher(environment -> - ((Place) environment.getSource()).stop instanceof RegularStop - ? ((RegularStop) ((Place) environment.getSource()).stop) - : null - ) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("flexibleArea") - .description("The flexible area related to the place.") - .type(GeoJSONCoordinatesScalar.getGraphQGeoJSONCoordinatesScalar()) - .dataFetcher(environment -> - ((Place) environment.getSource()).stop instanceof AreaStop - ? ((AreaStop) ((Place) environment.getSource()).stop).getGeometry().getCoordinates() - : null - ) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("bikeRentalStation") - .type(bikeRentalStationType) - .description("The bike rental station related to the place") - .dataFetcher(environment -> - ((Place) environment.getSource()).vertexType.equals(VertexType.VEHICLERENTAL) && + return ( + GraphQLObjectType.newObject() + .name("Place") + .description( + "Common super class for all places (stop places, quays, car parks, bike parks and bike rental stations )" + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("name") + .description( + "For transit quays, the name of the quay. For points of interest, the name of the POI." + ) + .type(Scalars.GraphQLString) + .dataFetcher(environment -> + GraphQLUtils.getTranslation(((Place) environment.getSource()).name, environment) + ) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("vertexType") + .description( + "Type of vertex. (Normal, Bike sharing station, Bike P+R, Transit quay) Mostly used for better localization of bike sharing and P+R station names" + ) + .type(EnumTypes.VERTEX_TYPE) + .dataFetcher(environment -> ((Place) environment.getSource()).vertexType) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("latitude") + .description("The latitude of the place.") + .type(new GraphQLNonNull(Scalars.GraphQLFloat)) + .dataFetcher(environment -> { + var coordinate = ((Place) environment.getSource()).coordinate; + if (coordinate == null) { + // TODO: Technically this is wrong, we should not return the place the user sends to + // us, as that is the only place the value can be null + return 0; + } + return coordinate.latitude(); + }) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("longitude") + .description("The longitude of the place.") + .type(new GraphQLNonNull(Scalars.GraphQLFloat)) + .dataFetcher(environment -> { + var coordinate = ((Place) environment.getSource()).coordinate; + if (coordinate == null) { + // TODO: Technically this is wrong, we should not return the place the user sends to + // us, as that is the only place the value can be null + return 0; + } + return coordinate.longitude(); + }) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("quay") + .description("The quay related to the place.") + .type(quayType) + .dataFetcher(environment -> + ((Place) environment.getSource()).stop instanceof RegularStop + ? (RegularStop) ((Place) environment.getSource()).stop + : null + ) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("flexibleArea") + .description("The flexible area related to the place.") + .type(GeoJSONCoordinatesScalar.getGraphQGeoJSONCoordinatesScalar()) + .dataFetcher(environment -> + ((Place) environment.getSource()).stop instanceof AreaStop + ? ((AreaStop) ((Place) environment.getSource()).stop).getGeometry().getCoordinates() + : null + ) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("bikeRentalStation") + .type(bikeRentalStationType) + .description("The bike rental station related to the place") + .dataFetcher(environment -> + ((Place) environment.getSource()).vertexType.equals(VertexType.VEHICLERENTAL) && ((Place) environment.getSource()).vehicleRentalPlace instanceof VehicleRentalStation - ? ((Place) environment.getSource()).vehicleRentalPlace - : null - ) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("rentalVehicle") - .type(rentalVehicleType) - .description("The rental vehicle related to the place") - .dataFetcher(environment -> - ((Place) environment.getSource()).vertexType.equals(VertexType.VEHICLERENTAL) && + ? ((Place) environment.getSource()).vehicleRentalPlace + : null + ) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("rentalVehicle") + .type(rentalVehicleType) + .description("The rental vehicle related to the place") + .dataFetcher(environment -> + ((Place) environment.getSource()).vertexType.equals(VertexType.VEHICLERENTAL) && ((Place) environment.getSource()).vehicleRentalPlace instanceof VehicleRentalVehicle - ? ((Place) environment.getSource()).vehicleRentalPlace - : null - ) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("viaLocationType") - .type(EnumTypes.VIA_LOCATION_TYPE) - .description( - "This defines if the place is a requested via location, and what kind it is. If the " + - "value is `null`, this place is not a via location." - ) - .dataFetcher(environment -> ((Place) environment.getSource()).viaLocationType) - .build() - ) - // .field(GraphQLFieldDefinition.newFieldDefinition() - // .name("bikePark") - // .type(bikeParkType) - // .description("The bike parking related to the place") - // .dataFetcher(environment -> ((Place) environment.getSource()).vertexType.equals(VertexType.BIKEPARK) ? - // index.graph.getService(VehicleRentalStationService.class) - // .getBikeParks() - // .stream() - // .filter(bikePark -> bikePark.id.equals(((Place) environment.getSource()).bikeParkId)) - // .findFirst() - // .orElse(null) - // : null) - // .build()) - // .field(GraphQLFieldDefinition.newFieldDefinition() - // .name("carPark") - // .type(carParkType) - // .description("The car parking related to the place") - // .dataFetcher(environment -> ((Place) environment.getSource()).vertexType.equals(VertexType.PARKANDRIDE) ? - // index.graph.getService(CarParkService.class) - // .getCarParks() - // .stream() - // .filter(carPark -> carPark.id.equals(((Place) environment.getSource()).carParkId)) - // .findFirst() - // .orElse(null) - // : null) - // .build()) - .build(); + ? ((Place) environment.getSource()).vehicleRentalPlace + : null + ) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("viaLocationType") + .type(EnumTypes.VIA_LOCATION_TYPE) + .description( + "This defines if the place is a requested via location, and what kind it is. If the " + + "value is `null`, this place is not a via location." + ) + .dataFetcher(environment -> ((Place) environment.getSource()).viaLocationType) + .build() + ) + // .field(GraphQLFieldDefinition.newFieldDefinition() + // .name("bikePark") + // .type(bikeParkType) + // .description("The bike parking related to the place") + // .dataFetcher(environment -> ((Place) environment.getSource()).vertexType.equals(VertexType.BIKEPARK) ? + // index.graph.getService(VehicleRentalStationService.class) + // .getBikeParks() + // .stream() + // .filter(bikePark -> bikePark.id.equals(((Place) environment.getSource()).bikeParkId)) + // .findFirst() + // .orElse(null) + // : null) + // .build()) + // .field(GraphQLFieldDefinition.newFieldDefinition() + // .name("carPark") + // .type(carParkType) + // .description("The car parking related to the place") + // .dataFetcher(environment -> ((Place) environment.getSource()).vertexType.equals(VertexType.PARKANDRIDE) ? + // index.graph.getService(CarParkService.class) + // .getCarParks() + // .stream() + // .filter(carPark -> carPark.id.equals(((Place) environment.getSource()).carParkId)) + // .findFirst() + // .orElse(null) + // : null) + // .build()) + .build() + ); } } diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RefetchTripPatternQuery.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RefetchTripPatternQuery.java index db0e73b8e07..df4b21d2f9f 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RefetchTripPatternQuery.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RefetchTripPatternQuery.java @@ -212,7 +212,15 @@ private DataFetcherResult refetchJourney(DataFetchingEnvironment var from = mapLocation(environment.getArgument("from")); var to = mapLocation(environment.getArgument("to")); - var refetcher = new RefetchItineraryService(ctx.getServerContext()); + var refetcher = new RefetchItineraryService( + ctx.getGraph(), + ctx.getTransitService(), + ctx.getTransitAlertService(), + ctx.getTransferService(), + ctx.getStreetDetailsService(), + ctx.getLinkingContextFactory(), + ctx.getStreetLimitationParametersService() + ); try { var itinerary = refetcher.refetchItinerary(from, to, legs, routeRequest); diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java index a43fbffba32..fa6a3615f82 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java @@ -49,8 +49,10 @@ public static GraphQLObjectType create( .description("The aimed date and time the trip starts.") .type(new GraphQLNonNull(dateTimeScalar)) .dataFetcher(env -> - // startTime is already adjusted for real-time - need to subtract delay to get aimed time - itinerary(env).startTime().minusSeconds(itinerary(env).departureDelay()) + itinerary(env) + .startTime() + // startTime is already adjusted for real-time - need to subtract delay to get aimed time + .minusSeconds(itinerary(env).departureDelay()) ) .build() ) @@ -68,8 +70,10 @@ public static GraphQLObjectType create( .description("The aimed date and time the trip ends.") .type(new GraphQLNonNull(dateTimeScalar)) .dataFetcher(env -> - // endTime is already adjusted for real-time - need to subtract delay to get aimed time - itinerary(env).endTime().minusSeconds(itinerary(env).arrivalDelay()) + itinerary(env) + .endTime() + // endTime is already adjusted for real-time - need to subtract delay to get aimed time + .minusSeconds(itinerary(env).arrivalDelay()) ) .build() ) diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java index 2cad2f2ed9b..66f756767f7 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java @@ -32,9 +32,9 @@ public class TripQuery { public static final String MAX_DIRECT_DURATION_FOR_MODE = "maxDirectDurationForMode"; public static final String TRIP_VIA_PARAMETER = "via"; public static final String DOC_VIA = """ - The list of via locations the journey is required to visit. All locations are - visited in the order they are listed. - """; + The list of via locations the journey is required to visit. All locations are + visited in the order they are listed. + """; private final TransmodelGraphQLPlanner graphQLPlanner; @@ -127,9 +127,9 @@ provided. The calculation comes with a significant overhead (10-20%% extra). Whe Maximum value: %d minutes (%dh) """.formatted( - transitTuningParameters.maxSearchWindow().toMinutes(), - transitTuningParameters.maxSearchWindow().toHours() - ) + transitTuningParameters.maxSearchWindow().toMinutes(), + transitTuningParameters.maxSearchWindow().toHours() + ) ) .type(Scalars.GraphQLInt) .build() diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java index 17a960be66a..811aa9df464 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java @@ -73,7 +73,8 @@ public static GraphQLObjectType create( .deprecate("Use routingErrors instead") .type(new GraphQLNonNull(new GraphQLList(Scalars.GraphQLString))) .dataFetcher(env -> - ((PlanResponse) env.getSource()).messages() + ((PlanResponse) env.getSource()) + .messages() .stream() .map(routingError -> PlannerErrorMapper.mapMessage(routingError).message) .map(Enum::name) @@ -91,7 +92,8 @@ public static GraphQLObjectType create( GraphQLArgument.newArgument().name("language").type(Scalars.GraphQLString).build() ) .dataFetcher(env -> - ((PlanResponse) env.getSource()).messages() + ((PlanResponse) env.getSource()) + .messages() .stream() .map(routingError -> PlannerErrorMapper.mapMessage(routingError).message) .map(message -> message.get(GraphQLUtils.getLocale(env))) diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaLocationInputType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaLocationInputType.java index db890bec3a1..03c18c6bd7e 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaLocationInputType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaLocationInputType.java @@ -21,19 +21,19 @@ public class ViaLocationInputType { private static final String INPUT_PASS_THROUGH_VIA_LOCATION = "TripPassThroughViaLocationInput"; private static final String DOC_VISIT_VIA_LOCATION = """ - A visit-via-location is a physical visit to one of the stop locations or coordinates listed. An - on-board visit does not count, the traveler must alight or board at the given stop for it to to - be accepted. To visit a coordinate, the traveler must walk (bike or drive) to the closest point - in the street network from a stop and back to another stop to join the transit network. - """; + A visit-via-location is a physical visit to one of the stop locations or coordinates listed. An + on-board visit does not count, the traveler must alight or board at the given stop for it to to + be accepted. To visit a coordinate, the traveler must walk (bike or drive) to the closest point + in the street network from a stop and back to another stop to join the transit network. + """; private static final String DOC_PASS_THROUGH_VIA_LOCATION = """ - One of the listed stop locations must be visited on-board a transit vehicle or the journey must - alight or board at the location. - """; + One of the listed stop locations must be visited on-board a transit vehicle or the journey must + alight or board at the location. + """; private static final String DOC_VIA_LOCATION = """ - A via-location is used to specifying a location as an intermediate place the router must - route through. The via-location is either a pass-through-location or a visit-via-location. - """; + A via-location is used to specifying a location as an intermediate place the router must + route through. The via-location is either a pass-through-location or a visit-via-location. + """; /* field constants */ @@ -53,14 +53,14 @@ be accepted. To visit a coordinate, the traveler must walk (bike or drive) to th "The label/name of the location. This is pass-through " + "information and is not used in routing."; private static final String DOC_MINIMUM_WAIT_TIME = """ - The minimum wait time is used to force the trip to stay the given duration at the - via-location before the trip is continued. - """; + The minimum wait time is used to force the trip to stay the given duration at the + via-location before the trip is continued. + """; private static final String DOC_STOP_LOCATION_IDS = """ - A list of stop locations. A stop location can be a quay, a stop place, a multimodal - stop place or a group of stop places. It is enough to visit ONE of the locations - listed. - """; + A list of stop locations. A stop location can be a quay, a stop place, a multimodal + stop place or a group of stop places. It is enough to visit ONE of the locations + listed. + """; private static final String DOC_COORDINATE = "A coordinate to route through."; static final GraphQLInputObjectType VISIT_VIA_LOCATION_INPUT = @@ -92,10 +92,10 @@ be accepted. To visit a coordinate, the traveler must walk (bike or drive) to th .description(DOC_PASS_THROUGH_VIA_LOCATION) .field(b -> b.name(FIELD_LABEL).description(DOC_LABEL).type(GraphQLString)) .field(b -> - // This is NOT nonNull, because we might add other parameters later, like 'list of line-ids' b .name(FIELD_STOP_LOCATION_IDS) .description(DOC_STOP_LOCATION_IDS) + // This is NOT nonNull, because we might add other parameters later, like 'list of line-ids' .type(requiredListOfNonNullStrings()) ) .build(); diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DateTimeScalarFactory.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DateTimeScalarFactory.java index c1464a1ca07..2520f6e2741 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DateTimeScalarFactory.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DateTimeScalarFactory.java @@ -17,11 +17,11 @@ public final class DateTimeScalarFactory { private static final String DOCUMENTATION = """ - DateTime format accepting ISO 8601 dates with time zone offset. + DateTime format accepting ISO 8601 dates with time zone offset. - Format: `YYYY-MM-DD'T'hh:mm[:ss](Z|±01:00)` + Format: `YYYY-MM-DD'T'hh:mm[:ss](Z|±01:00)` - Example: `2017-04-23T18:25:43+02:00` or `2017-04-23T16:25:43Z`"""; + Example: `2017-04-23T18:25:43+02:00` or `2017-04-23T16:25:43Z`"""; private static final DateTimeFormatter PARSER = OffsetDateTimeParser.LENIENT_PARSER; diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DoubleFunctionFactory.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DoubleFunctionFactory.java index 65bd8cb280f..602a10c1621 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DoubleFunctionFactory.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DoubleFunctionFactory.java @@ -17,15 +17,15 @@ public class DoubleFunctionFactory { private static final String TYPENAME = "DoubleFunction"; private static final String DOCUMENTATION = """ - A double function `f(t)` is used to calculate a value based on a variable (t). The variable can - be the duration/time or cost for a leg or section of a path/itinerary. The function - `f(t) = a + bt` has a constant (a) and a coefficient (b) that will be used in OTP to compute - `f(t)`. + A double function `f(t)` is used to calculate a value based on a variable (t). The variable can + be the duration/time or cost for a leg or section of a path/itinerary. The function + `f(t) = a + bt` has a constant (a) and a coefficient (b) that will be used in OTP to compute + `f(t)`. - Format: `a + b t`. Example: `30m + 2.0 t`. The constant `a` accept both whole numbers and - duration input format like: `60` = `60s` = `1m` and `3791` = `1h3m11s`. `b` must be a positive - decimal number between `0.0` and `100.0`. - """; + Format: `a + b t`. Example: `30m + 2.0 t`. The constant `a` accept both whole numbers and + duration input format like: `60` = `60s` = `1m` and `3791` = `1h3m11s`. `b` must be a positive + decimal number between `0.0` and `100.0`. + """; private DoubleFunctionFactory() {} diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/GeoJSONCoordinatesScalar.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/GeoJSONCoordinatesScalar.java index 64a18b33ce8..197f67f752d 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/GeoJSONCoordinatesScalar.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/GeoJSONCoordinatesScalar.java @@ -35,7 +35,7 @@ public class GeoJSONCoordinatesScalar { @Override public List> serialize(Object input) { if (input instanceof Coordinate[]) { - Coordinate[] coordinates = ((Coordinate[]) input); + Coordinate[] coordinates = (Coordinate[]) input; List> coordinateList = new ArrayList<>(); for (Coordinate coordinate : coordinates) { List coordinatePair = new ArrayList<>(); diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/TimeScalarFactory.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/TimeScalarFactory.java index 646b7eacc40..32ee14426e4 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/TimeScalarFactory.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/TimeScalarFactory.java @@ -40,7 +40,7 @@ public static GraphQLObjectType createSecondsSinceMidnightAsTimeObject() { .name("dayOffset") .description("Number of days offset from base line time") .type(Scalars.GraphQLInt) - .dataFetcher(environment -> ((Integer) environment.getSource()) / SECONDS_PER_DAY) + .dataFetcher(environment -> (Integer) environment.getSource() / SECONDS_PER_DAY) .build() ) .build(); @@ -55,9 +55,7 @@ public static GraphQLScalarType createSecondsSinceMidnightAsTimeStringScalar() { @Override public String serialize(Object input) { if (input instanceof Integer) { - return (LocalTime.ofSecondOfDay(((Integer) input % SECONDS_PER_DAY))).format( - FORMATTER - ); + return LocalTime.ofSecondOfDay((Integer) input % SECONDS_PER_DAY).format(FORMATTER); } return null; } diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/et/EstimatedCallType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/et/EstimatedCallType.java index b06592f3258..c1f6d4db96b 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/et/EstimatedCallType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/et/EstimatedCallType.java @@ -54,306 +54,310 @@ public static GraphQLObjectType create( GraphQLOutputType replacedByType, GraphQLScalarType dateTimeScalar ) { - return GraphQLObjectType.newObject() - .name("EstimatedCall") - .description( - "List of calls on quays as part of vehicle journeys. Updated with real time information where available" - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("quay") - .type(new GraphQLNonNull(quayType)) - .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).getStop()) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("scheduledQuay") - .description( - "The scheduled quay for this call. Equal to 'quay' unless the quay has been changed by a real time update" - ) - .type(new GraphQLNonNull(quayType)) - .dataFetcher(env -> { - TripTimeOnDate tripTimeOnDate = env.getSource(); - return tripTimeOnDate.getScheduledStop( - GqlUtil.getTransitService(env).findPattern(tripTimeOnDate.getTrip()) - ); - }) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("aimedArrivalTime") - .description("Scheduled time of arrival at quay. Not affected by read time updated") - .type(new GraphQLNonNull(dateTimeScalar)) - .dataFetcher(env -> calcTime(env, TripTimeOnDate::getScheduledArrival)) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("expectedArrivalTime") - .type(new GraphQLNonNull(dateTimeScalar)) - .description( - "Expected time of arrival at quay. Updated with real time information if available." - ) - .dataFetcher(env -> calcTime(env, TripTimeOnDate::getRealtimeArrival)) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("actualArrivalTime") - .type(dateTimeScalar) - .description( - "Actual time of arrival at quay. Updated from real time information if available." - ) - .dataFetcher(env -> calcTimeOptional(env, TripTimeOnDate::getActualArrival)) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("aimedDepartureTime") - .description("Scheduled time of departure from quay. Not affected by read time updated") - .type(new GraphQLNonNull(dateTimeScalar)) - .dataFetcher(env -> calcTime(env, TripTimeOnDate::getScheduledDeparture)) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("expectedDepartureTime") - .type(new GraphQLNonNull(dateTimeScalar)) - .description( - "Expected time of departure from quay. Updated with real time information if available." - ) - .dataFetcher(env -> calcTime(env, TripTimeOnDate::getRealtimeDeparture)) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("actualDepartureTime") - .type(dateTimeScalar) - .description( - "Actual time of departure from quay. Updated with real time information if available." - ) - .dataFetcher(env -> calcTimeOptional(env, TripTimeOnDate::getActualDeparture)) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("empiricalDelay") - .type(empiricalDelayType) - .description( - "The typical delay for this trip on this day for this stop based on historical data." - ) - .dataFetcher(EmpiricalDelayType::dataFetcherForTripTimeOnDate) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("timingPoint") - .type(new GraphQLNonNull(Scalars.GraphQLBoolean)) - .description( - "Whether this is a timing point or not. Boarding and alighting is not allowed at timing points." - ) - .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).isTimepoint()) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("realtime") - .type(new GraphQLNonNull(Scalars.GraphQLBoolean)) - .description("Whether this call has been updated with real time information.") - .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).isRealtime()) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("predictionInaccurate") - .type(new GraphQLNonNull(Scalars.GraphQLBoolean)) - .description("Whether the updated estimates are expected to be inaccurate.") - .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).isPredictionInaccurate()) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("realtimeState") - .type(new GraphQLNonNull(EnumTypes.REALTIME_STATE)) - .deprecate( - "Use realTimeJourneyState on datedServiceJourney for the journey's real-time state, or the individual boolean fields (cancellation, predictionInaccurate, extraCall) for the quay's state." - ) - .dataFetcher(EstimatedCallType::getRealtimeStateOnStop) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("occupancyStatus") - .type(new GraphQLNonNull(EnumTypes.OCCUPANCY_STATUS)) - .dataFetcher(env -> - OccupancyStatusMapper.mapStatus(((TripTimeOnDate) env.getSource()).getOccupancyStatus()) - ) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("stopPositionInPattern") - .type(new GraphQLNonNull(Scalars.GraphQLInt)) - .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).getStopPosition()) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("forBoarding") - .type(new GraphQLNonNull(Scalars.GraphQLBoolean)) - .description("Whether vehicle may be boarded at quay.") - .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).getPickupType().isRoutable()) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("forAlighting") - .type(new GraphQLNonNull(Scalars.GraphQLBoolean)) - .description("Whether vehicle may be alighted at quay.") - .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).getDropoffType().isRoutable()) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("requestStop") - .type(new GraphQLNonNull(Scalars.GraphQLBoolean)) - .description("Whether vehicle will only stop on request.") - .dataFetcher( - env -> ((TripTimeOnDate) env.getSource()).getDropoffType() == COORDINATE_WITH_DRIVER - ) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("cancellation") - .type(new GraphQLNonNull(Scalars.GraphQLBoolean)) - .description( - "Whether stop is cancelled. This means that either the " + - "ServiceJourney has a planned cancellation, the ServiceJourney has been " + - "cancelled by real-time data, or this particular StopPoint has been " + - "cancelled. This also means that both boarding and alighting has been " + - "cancelled." - ) - .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).isCanceledEffectively()) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("extraCall") - .type(new GraphQLNonNull(Scalars.GraphQLBoolean)) - .description("Whether this call is an extra call introduced by real-time data") - .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).isExtraCall()) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("date") - .type(new GraphQLNonNull(TransmodelScalars.DATE_SCALAR)) - .description("The date the estimated call is valid for.") - .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).getServiceDay()) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("serviceJourneyEstimatedCalls") - .type(new GraphQLNonNull(sjEstimatedCallType)) - .description("Estimated calls for the ServiceJourney on this date.") - .dataFetcher(DataFetchingEnvironment::getSource) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("serviceJourney") - .type(new GraphQLNonNull(serviceJourneyType)) - .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).getTrip()) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("datedServiceJourney") - .type(datedServiceJourneyType) - .dataFetcher(env -> - GqlUtil.getTransitService(env).getTripOnServiceDate( - new TripIdAndServiceDate( - env.getSource().getTrip().getId(), - env.getSource().getServiceDay() + return ( + GraphQLObjectType.newObject() + .name("EstimatedCall") + .description( + "List of calls on quays as part of vehicle journeys. Updated with real time information where available" + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("quay") + .type(new GraphQLNonNull(quayType)) + .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).getStop()) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("scheduledQuay") + .description( + "The scheduled quay for this call. Equal to 'quay' unless the quay has been changed by a real time update" + ) + .type(new GraphQLNonNull(quayType)) + .dataFetcher(env -> { + TripTimeOnDate tripTimeOnDate = env.getSource(); + return tripTimeOnDate.getScheduledStop( + GqlUtil.getTransitService(env).findPattern(tripTimeOnDate.getTrip()) + ); + }) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("aimedArrivalTime") + .description("Scheduled time of arrival at quay. Not affected by read time updated") + .type(new GraphQLNonNull(dateTimeScalar)) + .dataFetcher(env -> calcTime(env, TripTimeOnDate::getScheduledArrival)) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("expectedArrivalTime") + .type(new GraphQLNonNull(dateTimeScalar)) + .description( + "Expected time of arrival at quay. Updated with real time information if available." + ) + .dataFetcher(env -> calcTime(env, TripTimeOnDate::getRealtimeArrival)) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("actualArrivalTime") + .type(dateTimeScalar) + .description( + "Actual time of arrival at quay. Updated from real time information if available." + ) + .dataFetcher(env -> calcTimeOptional(env, TripTimeOnDate::getActualArrival)) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("aimedDepartureTime") + .description("Scheduled time of departure from quay. Not affected by read time updated") + .type(new GraphQLNonNull(dateTimeScalar)) + .dataFetcher(env -> calcTime(env, TripTimeOnDate::getScheduledDeparture)) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("expectedDepartureTime") + .type(new GraphQLNonNull(dateTimeScalar)) + .description( + "Expected time of departure from quay. Updated with real time information if available." + ) + .dataFetcher(env -> calcTime(env, TripTimeOnDate::getRealtimeDeparture)) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("actualDepartureTime") + .type(dateTimeScalar) + .description( + "Actual time of departure from quay. Updated with real time information if available." + ) + .dataFetcher(env -> calcTimeOptional(env, TripTimeOnDate::getActualDeparture)) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("empiricalDelay") + .type(empiricalDelayType) + .description( + "The typical delay for this trip on this day for this stop based on historical data." + ) + .dataFetcher(EmpiricalDelayType::dataFetcherForTripTimeOnDate) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("timingPoint") + .type(new GraphQLNonNull(Scalars.GraphQLBoolean)) + .description( + "Whether this is a timing point or not. Boarding and alighting is not allowed at timing points." + ) + .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).isTimepoint()) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("realtime") + .type(new GraphQLNonNull(Scalars.GraphQLBoolean)) + .description("Whether this call has been updated with real time information.") + .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).isRealtime()) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("predictionInaccurate") + .type(new GraphQLNonNull(Scalars.GraphQLBoolean)) + .description("Whether the updated estimates are expected to be inaccurate.") + .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).isPredictionInaccurate()) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("realtimeState") + .type(new GraphQLNonNull(EnumTypes.REALTIME_STATE)) + .deprecate( + "Use realTimeJourneyState on datedServiceJourney for the journey's real-time state, or the individual boolean fields (cancellation, predictionInaccurate, extraCall) for the quay's state." + ) + .dataFetcher(EstimatedCallType::getRealtimeStateOnStop) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("occupancyStatus") + .type(new GraphQLNonNull(EnumTypes.OCCUPANCY_STATUS)) + .dataFetcher(env -> + OccupancyStatusMapper.mapStatus( + ((TripTimeOnDate) env.getSource()).getOccupancyStatus() ) ) - ) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("destinationDisplay") - .type(destinationDisplayType) - .dataFetcher(DataFetchingEnvironment::getSource) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("notices") - .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(noticeType)))) - .dataFetcher(env -> { - TripTimeOnDate tripTimeOnDate = env.getSource(); - return GqlUtil.getTransitService(env).findNotices(tripTimeOnDate.getStopTimeKey()); - }) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("situations") - .withDirective(TransmodelDirectives.TIMING_DATA) - .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(ptSituationElementType)))) - .description("Get all relevant situations for this EstimatedCall.") - .dataFetcher(env -> - getAllRelevantAlerts(env.getSource(), GqlUtil.getTransitAlertService(env)) - ) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("bookingArrangements") - .description("Booking arrangements for this EstimatedCall.") - .type(bookingArrangementType) - .dataFetcher(env -> env.getSource().getPickupBookingInfo()) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("arrivalReplacedBy") - .description( - "Information about any trips replacing the current trip at the arrival of this call." - ) - .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(replacedByType)))) - .dataFetcher(env -> { - var source = env.getSource(); - return source.getArrivalReplacedBys(); - }) - .build() - ) - .field( - GraphQLFieldDefinition.newFieldDefinition() - .name("departureReplacedBy") - .description( - "Information about any trips replacing the current trip at the departure of this call." - ) - .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(replacedByType)))) - .dataFetcher(env -> { - var source = env.getSource(); - return source.getDepartureReplacedBys(); - }) - .build() - ) - // .field(GraphQLFieldDefinition.newFieldDefinition() - // .name("flexible") - // .type(Scalars.GraphQLBoolean) - // .description("Whether this call is part of a flexible trip. This means that arrival or departure " + - // "times are not scheduled but estimated within specified operating hours.") - // .dataFetcher(env -> ((TripTimeShort) env.getSource()).isFlexible()) - // .build()) - .build(); + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("stopPositionInPattern") + .type(new GraphQLNonNull(Scalars.GraphQLInt)) + .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).getStopPosition()) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("forBoarding") + .type(new GraphQLNonNull(Scalars.GraphQLBoolean)) + .description("Whether vehicle may be boarded at quay.") + .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).getPickupType().isRoutable()) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("forAlighting") + .type(new GraphQLNonNull(Scalars.GraphQLBoolean)) + .description("Whether vehicle may be alighted at quay.") + .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).getDropoffType().isRoutable()) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("requestStop") + .type(new GraphQLNonNull(Scalars.GraphQLBoolean)) + .description("Whether vehicle will only stop on request.") + .dataFetcher( + env -> ((TripTimeOnDate) env.getSource()).getDropoffType() == COORDINATE_WITH_DRIVER + ) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("cancellation") + .type(new GraphQLNonNull(Scalars.GraphQLBoolean)) + .description( + "Whether stop is cancelled. This means that either the " + + "ServiceJourney has a planned cancellation, the ServiceJourney has been " + + "cancelled by real-time data, or this particular StopPoint has been " + + "cancelled. This also means that both boarding and alighting has been " + + "cancelled." + ) + .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).isCanceledEffectively()) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("extraCall") + .type(new GraphQLNonNull(Scalars.GraphQLBoolean)) + .description("Whether this call is an extra call introduced by real-time data") + .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).isExtraCall()) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("date") + .type(new GraphQLNonNull(TransmodelScalars.DATE_SCALAR)) + .description("The date the estimated call is valid for.") + .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).getServiceDay()) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("serviceJourneyEstimatedCalls") + .type(new GraphQLNonNull(sjEstimatedCallType)) + .description("Estimated calls for the ServiceJourney on this date.") + .dataFetcher(DataFetchingEnvironment::getSource) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("serviceJourney") + .type(new GraphQLNonNull(serviceJourneyType)) + .dataFetcher(env -> ((TripTimeOnDate) env.getSource()).getTrip()) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("datedServiceJourney") + .type(datedServiceJourneyType) + .dataFetcher(env -> + GqlUtil.getTransitService(env).getTripOnServiceDate( + new TripIdAndServiceDate( + env.getSource().getTrip().getId(), + env.getSource().getServiceDay() + ) + ) + ) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("destinationDisplay") + .type(destinationDisplayType) + .dataFetcher(DataFetchingEnvironment::getSource) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("notices") + .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(noticeType)))) + .dataFetcher(env -> { + TripTimeOnDate tripTimeOnDate = env.getSource(); + return GqlUtil.getTransitService(env).findNotices(tripTimeOnDate.getStopTimeKey()); + }) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("situations") + .withDirective(TransmodelDirectives.TIMING_DATA) + .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(ptSituationElementType)))) + .description("Get all relevant situations for this EstimatedCall.") + .dataFetcher(env -> + getAllRelevantAlerts(env.getSource(), GqlUtil.getTransitAlertService(env)) + ) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("bookingArrangements") + .description("Booking arrangements for this EstimatedCall.") + .type(bookingArrangementType) + .dataFetcher(env -> env.getSource().getPickupBookingInfo()) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("arrivalReplacedBy") + .description( + "Information about any trips replacing the current trip at the arrival of this call." + ) + .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(replacedByType)))) + .dataFetcher(env -> { + var source = env.getSource(); + return source.getArrivalReplacedBys(); + }) + .build() + ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("departureReplacedBy") + .description( + "Information about any trips replacing the current trip at the departure of this call." + ) + .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(replacedByType)))) + .dataFetcher(env -> { + var source = env.getSource(); + return source.getDepartureReplacedBys(); + }) + .build() + ) + // .field(GraphQLFieldDefinition.newFieldDefinition() + // .name("flexible") + // .type(Scalars.GraphQLBoolean) + // .description("Whether this call is part of a flexible trip. This means that arrival or departure " + + // "times are not scheduled but estimated within specified operating hours.") + // .dataFetcher(env -> ((TripTimeShort) env.getSource()).isFlexible()) + // .build()) + .build() + ); } /// Determines the RealTimeState for the specific stop, if NO_DATA on Stop its RealTimeState is regarded as "Scheduled" @@ -373,7 +377,7 @@ private static Long calcTimeOptional( ) { TripTimeOnDate instance = env.getSource(); int offset = offsetProvider.applyAsInt(instance); - return (offset == -1) ? null : calcTime(instance, offset); + return offset == -1 ? null : calcTime(instance, offset); } /// Calculate the Epoch time in milliseconds from the given `instance` and `timeOffsetProvider`. @@ -463,8 +467,8 @@ private static void filterSituationsByDateAndStopConditions( Instant toTime ) { if (alertPatches != null) { - alertPatches.removeIf(alertPatch -> - !alertPatch.isActiveDuring(TimePeriod.of(fromTime, toTime)) + alertPatches.removeIf( + alertPatch -> !alertPatch.isActiveDuring(TimePeriod.of(fromTime, toTime)) ); } } diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/PtSituationElementType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/PtSituationElementType.java index 80494b97839..9a85ce38c7b 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/PtSituationElementType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/PtSituationElementType.java @@ -12,7 +12,9 @@ import graphql.schema.GraphQLOutputType; import graphql.schema.GraphQLScalarType; import graphql.schema.GraphQLTypeReference; +import java.time.Instant; import java.util.AbstractMap; +import java.util.Comparator; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @@ -64,7 +66,8 @@ public static GraphQLObjectType create( .deprecate("Use affects instead") .dataFetcher(environment -> GqlUtil.getTransitService(environment).getAgency( - ((TransitAlert) environment.getSource()).entities() + ((TransitAlert) environment.getSource()) + .entities() .stream() .filter(EntitySelector.Agency.class::isInstance) .map(EntitySelector.Agency.class::cast) @@ -82,7 +85,8 @@ public static GraphQLObjectType create( .deprecate("Use affects instead") .dataFetcher(environment -> { TransitService transitService = GqlUtil.getTransitService(environment); - return ((TransitAlert) environment.getSource()).entities() + return ((TransitAlert) environment.getSource()) + .entities() .stream() .filter(EntitySelector.Route.class::isInstance) .map(EntitySelector.Route.class::cast) @@ -99,7 +103,8 @@ public static GraphQLObjectType create( .deprecate("Use affects instead") .dataFetcher(environment -> { TransitService transitService = GqlUtil.getTransitService(environment); - return ((TransitAlert) environment.getSource()).entities() + return ((TransitAlert) environment.getSource()) + .entities() .stream() .filter(EntitySelector.Trip.class::isInstance) .map(EntitySelector.Trip.class::cast) @@ -116,7 +121,8 @@ public static GraphQLObjectType create( .deprecate("Use affects instead") .dataFetcher(environment -> { TransitService transitService = GqlUtil.getTransitService(environment); - return ((TransitAlert) environment.getSource()).entities() + return ((TransitAlert) environment.getSource()) + .entities() .stream() .filter(EntitySelector.Stop.class::isInstance) .map(EntitySelector.Stop.class::cast) @@ -134,7 +140,8 @@ public static GraphQLObjectType create( .deprecate("Use affects instead") .dataFetcher(environment -> { TransitService transitService = GqlUtil.getTransitService(environment); - return ((TransitAlert) environment.getSource()).entities() + return ((TransitAlert) environment.getSource()) + .entities() .stream() .filter(EntitySelector.Stop.class::isInstance) .map(EntitySelector.Stop.class::cast) @@ -231,19 +238,55 @@ public static GraphQLObjectType create( GraphQLFieldDefinition.newFieldDefinition() .name("validityPeriod") .type(validityPeriodType) + .deprecate("Use validityPeriods instead") .description("Period this situation is in effect") .dataFetcher(environment -> { TransitAlert alert = environment.getSource(); - Long startTime = alert.getEffectiveStartDate() != null - ? alert.getEffectiveStartDate().toEpochMilli() - : null; - Long endTime = alert.getEffectiveEndDate() != null - ? alert.getEffectiveEndDate().toEpochMilli() - : null; + Long startTime = + alert.getEffectiveStartDate() != null + ? alert.getEffectiveStartDate().toEpochMilli() + : null; + Long endTime = + alert.getEffectiveEndDate() != null + ? alert.getEffectiveEndDate().toEpochMilli() + : null; return new ValidityPeriod(startTime, endTime); }) .build() ) + .field( + GraphQLFieldDefinition.newFieldDefinition() + .name("validityPeriods") + .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(validityPeriodType)))) + .description( + "The periods in which this situation is valid, sorted in chronological order. " + + "There is always at least one period." + ) + .dataFetcher(environment -> { + TransitAlert alert = environment.getSource(); + return alert + .calendar() + .timePeriods() + .stream() + .map(period -> + new ValidityPeriod( + period.start().map(Instant::toEpochMilli).orElse(null), + period.end().map(Instant::toEpochMilli).orElse(null) + ) + ) + .sorted( + Comparator.comparing( + ValidityPeriod::startTime, + Comparator.nullsFirst(Comparator.naturalOrder()) + ).thenComparing( + ValidityPeriod::endTime, + Comparator.nullsLast(Comparator.naturalOrder()) + ) + ) + .toList(); + }) + .build() + ) .field( GraphQLFieldDefinition.newFieldDefinition() .name("reportType") diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/BikeParkType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/BikeParkType.java index 901130a7ec1..b8b99571c6c 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/BikeParkType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/BikeParkType.java @@ -45,7 +45,7 @@ public GraphQLObjectType createB(GraphQLInterfaceType placeInterface) { .name("spacesAvailable") .type(Scalars.GraphQLInt) .dataFetcher(environment -> { - var vehicleParking = ((VehicleParking) environment.getSource()); + var vehicleParking = (VehicleParking) environment.getSource(); var availability = vehicleParking.getAvailability(); if (availability != null) { return availability.getBicycleSpaces(); diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java index 554b0e8eede..fa65d6c6a7f 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java @@ -90,7 +90,7 @@ public GraphQLObjectType create( .build() ) .dataFetcher(env -> - (((StopLocation) env.getSource()).getName().toString(GqlUtil.getLocale(env))) + ((StopLocation) env.getSource()).getName().toString(GqlUtil.getLocale(env)) ) .build() ) @@ -98,14 +98,14 @@ public GraphQLObjectType create( GraphQLFieldDefinition.newFieldDefinition() .name("latitude") .type(Scalars.GraphQLFloat) - .dataFetcher(env -> (((StopLocation) env.getSource()).getLat())) + .dataFetcher(env -> ((StopLocation) env.getSource()).getLat()) .build() ) .field( GraphQLFieldDefinition.newFieldDefinition() .name("longitude") .type(Scalars.GraphQLFloat) - .dataFetcher(env -> (((StopLocation) env.getSource()).getLon())) + .dataFetcher(env -> ((StopLocation) env.getSource()).getLon()) .build() ) .field( @@ -142,7 +142,7 @@ public GraphQLObjectType create( .description("Whether this quay is suitable for wheelchair boarding.") .dataFetcher(env -> Objects.requireNonNullElse( - (((StopLocation) env.getSource()).getWheelchairAccessibility()), + ((StopLocation) env.getSource()).getWheelchairAccessibility(), Accessibility.NO_INFORMATION ) ) @@ -164,7 +164,7 @@ public GraphQLObjectType create( .description( "Public code used to identify this quay within the stop place. For instance a platform code." ) - .dataFetcher(env -> (((StopLocation) env.getSource()).getPlatformCode())) + .dataFetcher(env -> ((StopLocation) env.getSource()).getPlatformCode()) .build() ) .field( @@ -305,9 +305,8 @@ public GraphQLObjectType create( StopLocation stop = environment.getSource(); Long startTimeInput = environment.getArgument("startTime"); - Instant startTime = startTimeInput != null - ? Instant.ofEpochMilli(startTimeInput) - : Instant.now(); + Instant startTime = + startTimeInput != null ? Instant.ofEpochMilli(startTimeInput) : Instant.now(); List> filtersInput = environment.getArgument("filters"); JourneyWhiteListed whiteListed = new JourneyWhiteListed(environment, idMapper); diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopPlaceType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopPlaceType.java index fb2c5cccaa2..7ec6c241169 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopPlaceType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopPlaceType.java @@ -108,9 +108,9 @@ public GraphQLObjectType create( .build() ) .dataFetcher(environment -> - (((MonoOrMultiModalStation) environment.getSource()).getName().toString( - GqlUtil.getLocale(environment) - )) + ((MonoOrMultiModalStation) environment.getSource()) + .getName() + .toString(GqlUtil.getLocale(environment)) ) .build() ) @@ -118,18 +118,14 @@ public GraphQLObjectType create( GraphQLFieldDefinition.newFieldDefinition() .name("latitude") .type(Scalars.GraphQLFloat) - .dataFetcher(environment -> - (((MonoOrMultiModalStation) environment.getSource()).getLat()) - ) + .dataFetcher(environment -> ((MonoOrMultiModalStation) environment.getSource()).getLat()) .build() ) .field( GraphQLFieldDefinition.newFieldDefinition() .name("longitude") .type(Scalars.GraphQLFloat) - .dataFetcher(environment -> - (((MonoOrMultiModalStation) environment.getSource()).getLon()) - ) + .dataFetcher(environment -> ((MonoOrMultiModalStation) environment.getSource()).getLon()) .build() ) .field( @@ -179,7 +175,8 @@ public GraphQLObjectType create( .description("The transport modes of quays under this stop place.") .type(new GraphQLList(EnumTypes.TRANSPORT_MODE)) .dataFetcher(environment -> - ((MonoOrMultiModalStation) environment.getSource()).getChildStops() + ((MonoOrMultiModalStation) environment.getSource()) + .getChildStops() .stream() .map(StopLocation::getVehicleType) .filter(Objects::nonNull) @@ -193,7 +190,8 @@ public GraphQLObjectType create( .description("The transport submode serviced by this stop place.") .type(new GraphQLList(EnumTypes.TRANSPORT_SUBMODE)) .dataFetcher(environment -> - ((MonoOrMultiModalStation) environment.getSource()).getChildStops() + ((MonoOrMultiModalStation) environment.getSource()) + .getChildStops() .stream() .map(StopLocation::getNetexVehicleSubmode) .filter(it -> it != SubMode.UNKNOWN) @@ -255,7 +253,7 @@ public GraphQLObjectType create( .description("Returns parent stop for this stop") .type(new GraphQLTypeReference(NAME)) .dataFetcher(environment -> - (((MonoOrMultiModalStation) environment.getSource()).getParentStation()) + ((MonoOrMultiModalStation) environment.getSource()).getParentStation() ) .build() ) @@ -264,7 +262,8 @@ public GraphQLObjectType create( .name("tariffZones") .type(new GraphQLNonNull(new GraphQLList(tariffZoneType))) .dataFetcher(environment -> - ((MonoOrMultiModalStation) environment.getSource()).getChildStops() + ((MonoOrMultiModalStation) environment.getSource()) + .getChildStops() .stream() .flatMap(s -> s.getFareZones().stream()) .distinct() diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/BookingArrangementType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/BookingArrangementType.java index 7d3e077af3a..a2b5d29db6b 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/BookingArrangementType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/BookingArrangementType.java @@ -23,7 +23,7 @@ public static GraphQLObjectType create() { .name("contactPerson") .description("Name of person to contact") .type(Scalars.GraphQLString) - .dataFetcher(environment -> ((contactInfo(environment)).getContactPerson())) + .dataFetcher(environment -> contactInfo(environment).getContactPerson()) .build() ) .field( @@ -31,7 +31,7 @@ public static GraphQLObjectType create() { .name("email") .description("Email adress for contact") .type(Scalars.GraphQLString) - .dataFetcher(environment -> ((contactInfo(environment)).geteMail())) + .dataFetcher(environment -> contactInfo(environment).geteMail()) .build() ) .field( @@ -39,7 +39,7 @@ public static GraphQLObjectType create() { .name("url") .description("Url for contact") .type(Scalars.GraphQLString) - .dataFetcher(environment -> ((contactInfo(environment)).getBookingUrl())) + .dataFetcher(environment -> contactInfo(environment).getBookingUrl()) .build() ) .field( @@ -47,7 +47,7 @@ public static GraphQLObjectType create() { .name("phone") .description("Phone number for contact") .type(Scalars.GraphQLString) - .dataFetcher(environment -> ((contactInfo(environment)).getPhoneNumber())) + .dataFetcher(environment -> contactInfo(environment).getPhoneNumber()) .build() ) .field( @@ -55,7 +55,7 @@ public static GraphQLObjectType create() { .name("furtherDetails") .description("Textual description of how to get in contact") .type(Scalars.GraphQLString) - .dataFetcher(environment -> ((contactInfo(environment)).getAdditionalDetails())) + .dataFetcher(environment -> contactInfo(environment).getAdditionalDetails()) .build() ) .build(); @@ -67,7 +67,7 @@ public static GraphQLObjectType create() { .name("bookingMethods") .description("How should service be booked?") .type(new GraphQLList(EnumTypes.BOOKING_METHOD)) - .dataFetcher(environment -> ((bookingInfo(environment)).bookingMethods())) + .dataFetcher(environment -> bookingInfo(environment).bookingMethods()) .build() ) .field( @@ -76,7 +76,7 @@ public static GraphQLObjectType create() { .description("Latest time the service can be booked. ISO 8601 timestamp") .type(TransmodelScalars.LOCAL_TIME_SCALAR) .dataFetcher(environment -> { - final BookingTime latestBookingTime = (bookingInfo(environment)).getLatestBookingTime(); + final BookingTime latestBookingTime = bookingInfo(environment).getLatestBookingTime(); return latestBookingTime == null ? null : latestBookingTime.getTime(); }) .build() @@ -87,7 +87,7 @@ public static GraphQLObjectType create() { .description("How many days prior to the travel the service needs to be booked") .type(Scalars.GraphQLInt) .dataFetcher(environment -> { - final BookingTime latestBookingTime = (bookingInfo(environment)).getLatestBookingTime(); + final BookingTime latestBookingTime = bookingInfo(environment).getLatestBookingTime(); return latestBookingTime == null ? null : latestBookingTime.getDaysPrior(); }) .build() @@ -105,7 +105,7 @@ public static GraphQLObjectType create() { .name("minimumBookingPeriod") .description("Minimum period in advance service can be booked as a ISO 8601 duration") .type(Scalars.GraphQLString) - .dataFetcher(environment -> ((bookingInfo(environment)).getMinimumBookingNotice())) + .dataFetcher(environment -> bookingInfo(environment).getMinimumBookingNotice()) .build() ) .field( @@ -113,7 +113,7 @@ public static GraphQLObjectType create() { .name("bookingNote") .description("Textual description of booking arrangement for service") .type(Scalars.GraphQLString) - .dataFetcher(environment -> ((bookingInfo(environment)).getMessage())) + .dataFetcher(environment -> bookingInfo(environment).getMessage()) .build() ) .field( @@ -121,7 +121,7 @@ public static GraphQLObjectType create() { .name("bookingContact") .description("Who should ticket be contacted for booking") .type(contactType) - .dataFetcher(environment -> ((bookingInfo(environment)).getContactInfo())) + .dataFetcher(environment -> bookingInfo(environment).getContactInfo()) .build() ) .build(); diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyType.java index d98bbe692fd..daa474dd5b8 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyType.java @@ -68,7 +68,7 @@ public GraphQLObjectType create( .name("serviceJourney") .description("The service journey this Dated Service Journey is based on") .type(new GraphQLNonNull(serviceJourneyType)) - .dataFetcher(environment -> (tripOnServiceDate(environment).getTrip())) + .dataFetcher(environment -> tripOnServiceDate(environment).getTrip()) ) .field( GraphQLFieldDefinition.newFieldDefinition() diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/EmpiricalDelayType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/EmpiricalDelayType.java index 7eb4471329e..bb869149a9d 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/EmpiricalDelayType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/EmpiricalDelayType.java @@ -33,7 +33,7 @@ public static GraphQLObjectType create() { "The median/50% percentile. This value is in the middle of the distribution." ) .type(TransmodelScalars.DURATION_SCALAR) - .dataFetcher(e -> (empiricalDelay(e).p50())) + .dataFetcher(e -> empiricalDelay(e).p50()) .build() ) .field( @@ -43,7 +43,7 @@ public static GraphQLObjectType create() { "The 90% percentile. 90% of the values in the distribution is better and 10% is more delayed." ) .type(TransmodelScalars.DURATION_SCALAR) - .dataFetcher(e -> (empiricalDelay(e).p90())) + .dataFetcher(e -> empiricalDelay(e).p90()) .build() ) .build(); diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/ServiceJourneyType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/ServiceJourneyType.java index 008c52dca6c..d18c295ec51 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/ServiceJourneyType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/ServiceJourneyType.java @@ -58,7 +58,7 @@ public GraphQLObjectType create( GraphQLFieldDefinition.newFieldDefinition() .name("line") .type(new GraphQLNonNull(lineType)) - .dataFetcher(environment -> (trip(environment)).getRoute()) + .dataFetcher(environment -> trip(environment).getRoute()) .build() ) .field( @@ -69,7 +69,7 @@ public GraphQLObjectType create( .dataFetcher(environment -> GqlUtil.getTransitService(environment) .getTripCalendars() - .listServiceDates(((trip(environment)).getServiceId())) + .listServiceDates(trip(environment).getServiceId()) .stream() .sorted() .collect(Collectors.toList()) @@ -80,7 +80,7 @@ public GraphQLObjectType create( GraphQLFieldDefinition.newFieldDefinition() .name("transportMode") .type(EnumTypes.TRANSPORT_MODE) - .dataFetcher(environment -> ((trip(environment)).getMode())) + .dataFetcher(environment -> trip(environment).getMode()) .build() ) .field( @@ -88,7 +88,7 @@ public GraphQLObjectType create( .name("transportSubmode") .type(EnumTypes.TRANSPORT_SUBMODE) .dataFetcher(environment -> - TransmodelTransportSubmode.fromValue(((trip(environment))).getNetexSubMode()) + TransmodelTransportSubmode.fromValue(trip(environment).getNetexSubMode()) ) .build() ) @@ -99,7 +99,7 @@ public GraphQLObjectType create( .description( "Publicly announced code for service journey, differentiating it from other service journeys for the same line." ) - .dataFetcher(environment -> ((trip(environment)).getShortName())) + .dataFetcher(environment -> trip(environment).getShortName()) .build() ) .field( @@ -107,14 +107,14 @@ public GraphQLObjectType create( .name("privateCode") .type(Scalars.GraphQLString) .description("For internal use by operators.") - .dataFetcher(environment -> ((trip(environment)).getNetexInternalPlanningCode())) + .dataFetcher(environment -> trip(environment).getNetexInternalPlanningCode()) .build() ) .field( GraphQLFieldDefinition.newFieldDefinition() .name("operator") .type(operatorType) - .dataFetcher(environment -> ((trip(environment)).getOperator())) + .dataFetcher(environment -> trip(environment).getOperator()) .build() ) .field( diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/support/AbortOnUnprocessableRequestExecutionStrategy.java b/application/src/main/java/org/opentripplanner/apis/transmodel/support/AbortOnUnprocessableRequestExecutionStrategy.java index 009d592b5d7..79efb00f849 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/support/AbortOnUnprocessableRequestExecutionStrategy.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/support/AbortOnUnprocessableRequestExecutionStrategy.java @@ -21,7 +21,8 @@ */ public class AbortOnUnprocessableRequestExecutionStrategy extends AsyncExecutionStrategy - implements Closeable { + implements Closeable +{ private static final Logger LOG = LoggerFactory.getLogger( AbortOnUnprocessableRequestExecutionStrategy.class diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/support/GqlUtil.java b/application/src/main/java/org/opentripplanner/apis/transmodel/support/GqlUtil.java index d37c74f2f55..83526f275d6 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/support/GqlUtil.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/support/GqlUtil.java @@ -42,29 +42,21 @@ public static TransitAlertService getTransitAlertService(DataFetchingEnvironment } public static VehicleRentalService getVehicleRentalService(DataFetchingEnvironment environment) { - return ( - (TransmodelRequestContext) environment.getContext() - ).getServerContext().vehicleRentalService(); + return ((TransmodelRequestContext) environment.getContext()).getVehicleRentalService(); } public static VehicleParkingService getVehicleParkingService( DataFetchingEnvironment environment ) { - return ( - (TransmodelRequestContext) environment.getContext() - ).getServerContext().vehicleParkingService(); + return ((TransmodelRequestContext) environment.getContext()).getVehicleParkingService(); } public static NearbyPlaceFinder getNearbyPlaceFinder(DataFetchingEnvironment environment) { - return ( - (TransmodelRequestContext) environment.getContext() - ).getServerContext().nearbyPlaceFinder(); + return ((TransmodelRequestContext) environment.getContext()).getNearbyPlaceFinder(); } public static NearbyStopFinder getNearbyStopFinder(DataFetchingEnvironment environment) { - return ( - (TransmodelRequestContext) environment.getContext() - ).getServerContext().nearbyStopFinder(); + return ((TransmodelRequestContext) environment.getContext()).getNearbyStopFinder(); } public static GraphQLFieldDefinition newTransitIdField(FeedScopedIdMapper idMapper) { diff --git a/application/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/application/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java index 465ffb9a79a..1b983a381e7 100644 --- a/application/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java +++ b/application/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -165,14 +165,15 @@ static StyleSpec build( List extraRasterSources = extraLayers .stream() - .map(l -> - (TileSource) new RasterSource( - l.name(), - List.of(l.templateUrl()), - 19, - l.tileSize(), - l.attribution() - ) + .map( + l -> + (TileSource) new RasterSource( + l.name(), + List.of(l.templateUrl()), + 19, + l.tileSize(), + l.attribution() + ) ) .toList(); var allSources = ListUtils.combine(BACKGROUND_LAYERS, extraRasterSources, vectorSources); diff --git a/application/src/main/java/org/opentripplanner/apis/vectortiles/DebugVectorTilesResource.java b/application/src/main/java/org/opentripplanner/apis/vectortiles/DebugVectorTilesResource.java index c5887fce728..c356d1079be 100644 --- a/application/src/main/java/org/opentripplanner/apis/vectortiles/DebugVectorTilesResource.java +++ b/application/src/main/java/org/opentripplanner/apis/vectortiles/DebugVectorTilesResource.java @@ -220,7 +220,9 @@ private static LayerBuilder createLayerBuilder( layerParameters, locale, // There are not many GroupStops, so we can just list them all. - context.transitService().listGroupStops() + context + .transitService() + .listGroupStops() ); case GeofencingZones -> new GeofencingZonesLayerBuilder( context.vehicleRentalService(), diff --git a/application/src/main/java/org/opentripplanner/datastore/file/ZipFileDataSource.java b/application/src/main/java/org/opentripplanner/datastore/file/ZipFileDataSource.java index e988cc1d670..3c9ba6b75f9 100644 --- a/application/src/main/java/org/opentripplanner/datastore/file/ZipFileDataSource.java +++ b/application/src/main/java/org/opentripplanner/datastore/file/ZipFileDataSource.java @@ -22,7 +22,8 @@ */ public class ZipFileDataSource extends AbstractFileDataSource - implements CompositeDataSource, ZipFileEntryParent { + implements CompositeDataSource, ZipFileEntryParent +{ private static final Logger LOG = LoggerFactory.getLogger(ZipFileDataSource.class); private final Collection content = new ArrayList<>(); diff --git a/application/src/main/java/org/opentripplanner/framework/graphql/DefaultCountedConnection.java b/application/src/main/java/org/opentripplanner/framework/graphql/DefaultCountedConnection.java index da1914def91..1e7fbdca770 100644 --- a/application/src/main/java/org/opentripplanner/framework/graphql/DefaultCountedConnection.java +++ b/application/src/main/java/org/opentripplanner/framework/graphql/DefaultCountedConnection.java @@ -13,7 +13,8 @@ */ public class DefaultCountedConnection extends DefaultConnection - implements CountedConnection { + implements CountedConnection +{ private final Integer totalCount; diff --git a/application/src/main/java/org/opentripplanner/framework/graphql/SimpleCountedListConnection.java b/application/src/main/java/org/opentripplanner/framework/graphql/SimpleCountedListConnection.java index fa367871a85..f583896f534 100644 --- a/application/src/main/java/org/opentripplanner/framework/graphql/SimpleCountedListConnection.java +++ b/application/src/main/java/org/opentripplanner/framework/graphql/SimpleCountedListConnection.java @@ -11,8 +11,9 @@ * This class is a version of the {@link SimpleListConnection} that returns a * {@link CountedConnection}. */ -public class SimpleCountedListConnection - implements DataFetcher>, TrivialDataFetcher> { +public class SimpleCountedListConnection implements + DataFetcher>, + TrivialDataFetcher> { private final List data; diff --git a/application/src/main/java/org/opentripplanner/framework/model/Gram.java b/application/src/main/java/org/opentripplanner/framework/model/Gram.java index 344b0f67de5..a8493d099e4 100644 --- a/application/src/main/java/org/opentripplanner/framework/model/Gram.java +++ b/application/src/main/java/org/opentripplanner/framework/model/Gram.java @@ -108,7 +108,7 @@ public String toString() { return value / GRAM_PRECISION + "g"; } if (Math.abs(value) > 1000) { - return (value / 1000.0) + "g"; + return value / 1000.0 + "g"; } return value + "mg"; } diff --git a/application/src/main/java/org/opentripplanner/framework/transaction/internal/DefaultUpdateManager.java b/application/src/main/java/org/opentripplanner/framework/transaction/internal/DefaultUpdateManager.java index c263c7919c0..c4e2777e451 100644 --- a/application/src/main/java/org/opentripplanner/framework/transaction/internal/DefaultUpdateManager.java +++ b/application/src/main/java/org/opentripplanner/framework/transaction/internal/DefaultUpdateManager.java @@ -52,9 +52,10 @@ class DefaultUpdateManager implements UpdateManager { new LinkedBlockingQueue<>(), threadFactory ); - this.periodicCommitScheduler = commitInterval != null && !commitInterval.isZero() - ? new PeriodicCommitScheduler(name, commitInterval, threadFactory, this::submitCommit) - : null; + this.periodicCommitScheduler = + commitInterval != null && !commitInterval.isZero() + ? new PeriodicCommitScheduler(name, commitInterval, threadFactory, this::submitCommit) + : null; } @Override diff --git a/application/src/main/java/org/opentripplanner/gbfs/GbfsFeedLoaderImpl.java b/application/src/main/java/org/opentripplanner/gbfs/GbfsFeedLoaderImpl.java index 519bef67571..af76c0641dd 100644 --- a/application/src/main/java/org/opentripplanner/gbfs/GbfsFeedLoaderImpl.java +++ b/application/src/main/java/org/opentripplanner/gbfs/GbfsFeedLoaderImpl.java @@ -19,8 +19,10 @@ * Base class for managing the state and loading of complete GBFS datasets, and updating them * according to individual feed's TTL rules. */ -public abstract class GbfsFeedLoaderImpl> - implements GbfsFeedLoader { +public abstract class GbfsFeedLoaderImpl< + N, + F extends GbfsFeedDetails +> implements GbfsFeedLoader { private static final Logger LOG = LoggerFactory.getLogger(GbfsFeedLoaderImpl.class); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); @@ -191,11 +193,12 @@ private void updateNextFetchTime(T feedData) { // Fetch lastUpdated and ttl from the resulting class. Due to type erasure we don't know the actual // class, and have to use introspection to get the method references, as they do not share a supertype. Object lastUpdatedValue = implementingClass.getMethod("getLastUpdated").invoke(feedData); - Integer lastUpdated = lastUpdatedValue == null - ? null - : (lastUpdatedValue instanceof Date + Integer lastUpdated = + lastUpdatedValue == null + ? null + : lastUpdatedValue instanceof Date ? (int) ((Date) lastUpdatedValue).getTime() - : (Integer) lastUpdatedValue); + : (Integer) lastUpdatedValue; Integer ttl = (Integer) implementingClass.getMethod("getTtl").invoke(feedData); if (lastUpdated == null || ttl == null) { nextUpdate = getCurrentTimeSeconds(); diff --git a/application/src/main/java/org/opentripplanner/gbfs/v2/GbfsFeedLoader.java b/application/src/main/java/org/opentripplanner/gbfs/v2/GbfsFeedLoader.java index d522f3c1ec6..d3ed1ceb764 100644 --- a/application/src/main/java/org/opentripplanner/gbfs/v2/GbfsFeedLoader.java +++ b/application/src/main/java/org/opentripplanner/gbfs/v2/GbfsFeedLoader.java @@ -18,7 +18,8 @@ * to individual feed's TTL rules. */ public class GbfsFeedLoader - extends GbfsFeedLoaderImpl { + extends GbfsFeedLoaderImpl +{ /** * Sets up updaters for the feeds listed in the auto-configuration file. @@ -32,9 +33,10 @@ public static GbfsFeedLoader create( GBFS data = autoConfiguration.mapTo(GBFS.class); // Pick first language if none defined - GBFSFeeds feeds = languageCode == null - ? data.getFeedsData().values().iterator().next() - : data.getFeedsData().get(languageCode); + GBFSFeeds feeds = + languageCode == null + ? data.getFeedsData().values().iterator().next() + : data.getFeedsData().get(languageCode); if (feeds == null) { throw new GbfsConstructionException( "Language " + languageCode + " does not exist in feed " + autoConfiguration.url() diff --git a/application/src/main/java/org/opentripplanner/gbfs/v2/GbfsFreeVehicleStatusMapper.java b/application/src/main/java/org/opentripplanner/gbfs/v2/GbfsFreeVehicleStatusMapper.java index 2f87bac7629..7c92c5d84a0 100644 --- a/application/src/main/java/org/opentripplanner/gbfs/v2/GbfsFreeVehicleStatusMapper.java +++ b/application/src/main/java/org/opentripplanner/gbfs/v2/GbfsFreeVehicleStatusMapper.java @@ -65,7 +65,7 @@ public VehicleRentalVehicle mapFreeVehicleStatus(GBFSBike vehicle) { vehicle.getVehicleTypeId() != null && vehicleTypes.get(vehicle.getVehicleTypeId()) != null && vehicleTypes.get(vehicle.getVehicleTypeId()).propulsionType() != - RentalVehicleType.PropulsionType.HUMAN && + RentalVehicleType.PropulsionType.HUMAN && rangeMeters == null ) { return null; diff --git a/application/src/main/java/org/opentripplanner/gbfs/v2/GbfsGeofencingZoneMapper.java b/application/src/main/java/org/opentripplanner/gbfs/v2/GbfsGeofencingZoneMapper.java index 03fe60f605a..6424b4fdc8e 100644 --- a/application/src/main/java/org/opentripplanner/gbfs/v2/GbfsGeofencingZoneMapper.java +++ b/application/src/main/java/org/opentripplanner/gbfs/v2/GbfsGeofencingZoneMapper.java @@ -16,7 +16,8 @@ * within a zone becomes a separate GeofencingZone with its own priority. */ class GbfsGeofencingZoneMapper - extends org.opentripplanner.gbfs.GbfsGeofencingZoneMapper { + extends org.opentripplanner.gbfs.GbfsGeofencingZoneMapper +{ public GbfsGeofencingZoneMapper(String systemId) { super(systemId); diff --git a/application/src/main/java/org/opentripplanner/gbfs/v2/GbfsStationStatusMapper.java b/application/src/main/java/org/opentripplanner/gbfs/v2/GbfsStationStatusMapper.java index b700d2d8d2e..cf498834b0b 100644 --- a/application/src/main/java/org/opentripplanner/gbfs/v2/GbfsStationStatusMapper.java +++ b/application/src/main/java/org/opentripplanner/gbfs/v2/GbfsStationStatusMapper.java @@ -44,24 +44,24 @@ VehicleRentalStation mapStationStatus(VehicleRentalStation station) { } GBFSStation status = statusLookup.get(station.stationId()); - int vehiclesAvailable = status.getNumBikesAvailable() != null - ? status.getNumBikesAvailable() - : 0; - - Map vehicleTypesAvailable = status.getVehicleTypesAvailable() != - null - ? status - .getVehicleTypesAvailable() - .stream() - .filter(e -> containsVehicleType(e, status, station.network())) - .collect(Collectors.toMap(e -> vehicleTypes.get(e.getVehicleTypeId()), e -> e.getCount())) - : Map.of(RentalVehicleType.getDefaultType(station.network()), vehiclesAvailable); + int vehiclesAvailable = + status.getNumBikesAvailable() != null ? status.getNumBikesAvailable() : 0; + + Map vehicleTypesAvailable = + status.getVehicleTypesAvailable() != null + ? status + .getVehicleTypesAvailable() + .stream() + .filter(e -> containsVehicleType(e, status, station.network())) + .collect( + Collectors.toMap(e -> vehicleTypes.get(e.getVehicleTypeId()), e -> e.getCount()) + ) + : Map.of(RentalVehicleType.getDefaultType(station.network()), vehiclesAvailable); int vehiclesDisabled = status.getNumBikesDisabled() != null ? status.getNumBikesDisabled() : 0; - int spacesAvailable = status.getNumDocksAvailable() != null - ? status.getNumDocksAvailable() - : Integer.MAX_VALUE; + int spacesAvailable = + status.getNumDocksAvailable() != null ? status.getNumDocksAvailable() : Integer.MAX_VALUE; var vehicleSpacesAvailable = vehicleSpaces(status); diff --git a/application/src/main/java/org/opentripplanner/gbfs/v3/GbfsFeedLoader.java b/application/src/main/java/org/opentripplanner/gbfs/v3/GbfsFeedLoader.java index fb02b036d62..028676e5625 100644 --- a/application/src/main/java/org/opentripplanner/gbfs/v3/GbfsFeedLoader.java +++ b/application/src/main/java/org/opentripplanner/gbfs/v3/GbfsFeedLoader.java @@ -16,7 +16,8 @@ * to individual feed's TTL rules. */ public class GbfsFeedLoader - extends GbfsFeedLoaderImpl { + extends GbfsFeedLoaderImpl +{ /** * Sets up updaters for the feeds listed in the auto-configuration file. diff --git a/application/src/main/java/org/opentripplanner/gbfs/v3/GbfsGeofencingZoneMapper.java b/application/src/main/java/org/opentripplanner/gbfs/v3/GbfsGeofencingZoneMapper.java index 29dca4fb050..22fe61bb4af 100644 --- a/application/src/main/java/org/opentripplanner/gbfs/v3/GbfsGeofencingZoneMapper.java +++ b/application/src/main/java/org/opentripplanner/gbfs/v3/GbfsGeofencingZoneMapper.java @@ -18,7 +18,8 @@ * within a zone becomes a separate GeofencingZone with its own priority. */ class GbfsGeofencingZoneMapper - extends org.opentripplanner.gbfs.GbfsGeofencingZoneMapper { + extends org.opentripplanner.gbfs.GbfsGeofencingZoneMapper +{ public GbfsGeofencingZoneMapper(String systemId) { super(systemId); diff --git a/application/src/main/java/org/opentripplanner/gbfs/v3/GbfsStationStatusMapper.java b/application/src/main/java/org/opentripplanner/gbfs/v3/GbfsStationStatusMapper.java index 43aba2d64ca..241064a4dc1 100644 --- a/application/src/main/java/org/opentripplanner/gbfs/v3/GbfsStationStatusMapper.java +++ b/application/src/main/java/org/opentripplanner/gbfs/v3/GbfsStationStatusMapper.java @@ -44,26 +44,25 @@ VehicleRentalStation mapStationStatus(VehicleRentalStation station) { } GBFSStation status = statusLookup.get(station.stationId()); - int vehiclesAvailable = status.getNumVehiclesAvailable() != null - ? status.getNumVehiclesAvailable() - : 0; - - Map vehicleTypesAvailable = status.getVehicleTypesAvailable() != - null - ? status - .getVehicleTypesAvailable() - .stream() - .filter(e -> containsVehicleType(e, status, station.network())) - .collect(Collectors.toMap(e -> vehicleTypes.get(e.getVehicleTypeId()), e -> e.getCount())) - : Map.of(RentalVehicleType.getDefaultType(station.network()), vehiclesAvailable); - - int vehiclesDisabled = status.getNumVehiclesDisabled() != null - ? status.getNumVehiclesDisabled() - : 0; - - int spacesAvailable = status.getNumDocksAvailable() != null - ? status.getNumDocksAvailable() - : Integer.MAX_VALUE; + int vehiclesAvailable = + status.getNumVehiclesAvailable() != null ? status.getNumVehiclesAvailable() : 0; + + Map vehicleTypesAvailable = + status.getVehicleTypesAvailable() != null + ? status + .getVehicleTypesAvailable() + .stream() + .filter(e -> containsVehicleType(e, status, station.network())) + .collect( + Collectors.toMap(e -> vehicleTypes.get(e.getVehicleTypeId()), e -> e.getCount()) + ) + : Map.of(RentalVehicleType.getDefaultType(station.network()), vehiclesAvailable); + + int vehiclesDisabled = + status.getNumVehiclesDisabled() != null ? status.getNumVehiclesDisabled() : 0; + + int spacesAvailable = + status.getNumDocksAvailable() != null ? status.getNumDocksAvailable() : Integer.MAX_VALUE; var vehicleSpacesAvailable = vehicleSpaces(status); diff --git a/application/src/main/java/org/opentripplanner/gbfs/v3/GbfsVehicleStatusMapper.java b/application/src/main/java/org/opentripplanner/gbfs/v3/GbfsVehicleStatusMapper.java index 4d47bfb9a33..87f7db8449d 100644 --- a/application/src/main/java/org/opentripplanner/gbfs/v3/GbfsVehicleStatusMapper.java +++ b/application/src/main/java/org/opentripplanner/gbfs/v3/GbfsVehicleStatusMapper.java @@ -60,7 +60,7 @@ public VehicleRentalVehicle mapVehicleStatus(GBFSVehicle vehicle) { vehicle.getVehicleTypeId() != null && vehicleTypes.get(vehicle.getVehicleTypeId()) != null && vehicleTypes.get(vehicle.getVehicleTypeId()).propulsionType() != - RentalVehicleType.PropulsionType.HUMAN && + RentalVehicleType.PropulsionType.HUMAN && rangeMeters == null ) { return null; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/GraphStats.java b/application/src/main/java/org/opentripplanner/graph_builder/GraphStats.java index b28aefacdfa..e01e0ecf3e8 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/GraphStats.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/GraphStats.java @@ -216,16 +216,14 @@ class CommandPatternStats { public void run() { LOG.info("counting number of trips per pattern..."); try { - writer.writeRecord( - new String[] { - "nTripsInPattern", - "frequency", - "cumulativePatterns", - "empiricalDistPatterns", - "cumulativeTrips", - "empiricalDistTrips", - } - ); + writer.writeRecord(new String[] { + "nTripsInPattern", + "frequency", + "cumulativePatterns", + "empiricalDistPatterns", + "cumulativeTrips", + "empiricalDistTrips", + }); Collection patterns = transitRepository.getAllTripPatterns(); Multiset counts = TreeMultiset.create(); int nPatterns = patterns.size(); @@ -243,16 +241,14 @@ public void run() { for (Multiset.Entry count : counts.entrySet()) { cPatterns += count.getCount(); cTrips += count.getCount() * count.getElement(); - writer.writeRecord( - new String[] { - count.getElement().toString(), - Integer.toString(count.getCount()), - Integer.toString(cPatterns), - Double.toString(cPatterns / (double) nPatterns), - Integer.toString(cTrips), - Double.toString(cTrips / (double) nTrips), - } - ); + writer.writeRecord(new String[] { + count.getElement().toString(), + Integer.toString(count.getCount()), + Integer.toString(cPatterns), + Double.toString(cPatterns / (double) nPatterns), + Integer.toString(cTrips), + Double.toString(cTrips / (double) nTrips), + }); } } catch (IOException e) { LOG.error("Exception writing CSV: {}", e.getMessage()); diff --git a/application/src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueSummary.java b/application/src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueSummary.java index da3110d0ce7..f5af89e4171 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueSummary.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueSummary.java @@ -42,16 +42,14 @@ public static DataImportIssueSummary combine( DataImportIssueSummary second ) { var combined = new HashMap<>(first.asMap()); - second - .asMap() - .forEach((type, count) -> { - if (combined.containsKey(type)) { - var countSoFar = combined.get(type); - combined.put(type, count + countSoFar); - } else { - combined.put(type, count); - } - }); + second.asMap().forEach((type, count) -> { + if (combined.containsKey(type)) { + var countSoFar = combined.get(type); + combined.put(type, count + countSoFar); + } else { + combined.put(type, count); + } + }); return new DataImportIssueSummary(combined); } diff --git a/application/src/main/java/org/opentripplanner/graph_builder/issue/report/BucketKey.java b/application/src/main/java/org/opentripplanner/graph_builder/issue/report/BucketKey.java index 9c2c74ae263..39d15856afe 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/issue/report/BucketKey.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issue/report/BucketKey.java @@ -7,7 +7,7 @@ String key() { } String label() { - String bucketIndexString = this.index != null ? (" " + this.index) : ""; + String bucketIndexString = this.index != null ? " " + this.index : ""; return this.issueType + bucketIndexString; } diff --git a/application/src/main/java/org/opentripplanner/graph_builder/issues/BogusShapeGeometryCaught.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/BogusShapeGeometryCaught.java index bf9a9fd0de7..686d5737e59 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/issues/BogusShapeGeometryCaught.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issues/BogusShapeGeometryCaught.java @@ -4,8 +4,11 @@ import org.opentripplanner.graph_builder.issue.api.DataImportIssue; import org.opentripplanner.model.StopTime; -public record BogusShapeGeometryCaught(FeedScopedId shapeId, StopTime stA, StopTime stB) implements - DataImportIssue { +public record BogusShapeGeometryCaught( + FeedScopedId shapeId, + StopTime stA, + StopTime stB +) implements DataImportIssue { private static final String FMT = "Shape_dist_traveled for shape_id %s is in conflict with stop " + "times %s and %s; shape_dist_traveled will not be used"; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/issues/InvalidVehicleParkingCapacity.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/InvalidVehicleParkingCapacity.java index 9375ac32d05..246b89b04f9 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/issues/InvalidVehicleParkingCapacity.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issues/InvalidVehicleParkingCapacity.java @@ -3,8 +3,10 @@ import org.opentripplanner.graph_builder.issue.api.DataImportIssue; import org.opentripplanner.osm.model.OsmEntity; -public record InvalidVehicleParkingCapacity(OsmEntity entity, String capacityValue) implements - DataImportIssue { +public record InvalidVehicleParkingCapacity( + OsmEntity entity, + String capacityValue +) implements DataImportIssue { private static final String FMT = "Capacity for osm node %d is not a number: '%s'; it's replaced with '-1' (unknown)."; private static final String HTMLFMT = diff --git a/application/src/main/java/org/opentripplanner/graph_builder/issues/ParkAndRideEntranceRemoved.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/ParkAndRideEntranceRemoved.java index d3f5425c896..7892d3aa025 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/issues/ParkAndRideEntranceRemoved.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issues/ParkAndRideEntranceRemoved.java @@ -5,8 +5,9 @@ import org.opentripplanner.service.vehicleparking.model.VehicleParkingEntrance; import org.opentripplanner.street.geometry.GeometryUtils; -public record ParkAndRideEntranceRemoved(VehicleParkingEntrance vehicleParkingEntrance) implements - DataImportIssue { +public record ParkAndRideEntranceRemoved( + VehicleParkingEntrance vehicleParkingEntrance +) implements DataImportIssue { private static final String FMT = "Park and ride entrance '%s' is removed because it's StreetVertex ('%s') is removed in a previous step."; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/issues/ShapeGeometryTooFar.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/ShapeGeometryTooFar.java index 4914ec5a655..db10bdc62ae 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/issues/ShapeGeometryTooFar.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issues/ShapeGeometryTooFar.java @@ -3,8 +3,10 @@ import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; -public record ShapeGeometryTooFar(FeedScopedId tripId, FeedScopedId shapeId) implements - DataImportIssue { +public record ShapeGeometryTooFar( + FeedScopedId tripId, + FeedScopedId shapeId +) implements DataImportIssue { private static final String FMT = "Trip %s is too far from shape geometry %s, using straight line path instead"; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/model/ConfiguredCompositeDataSource.java b/application/src/main/java/org/opentripplanner/graph_builder/model/ConfiguredCompositeDataSource.java index 11df8f6e708..6e0e1963d74 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/model/ConfiguredCompositeDataSource.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/model/ConfiguredCompositeDataSource.java @@ -5,8 +5,7 @@ /** * A pair linking together a data source and its custom configuration. */ -public class ConfiguredCompositeDataSource - extends ConfiguredDataSource { +public class ConfiguredCompositeDataSource extends ConfiguredDataSource { public ConfiguredCompositeDataSource(CompositeDataSource dataSource, T config) { super(dataSource, config); diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/AddTransitEntitiesToTimetable.java b/application/src/main/java/org/opentripplanner/graph_builder/module/AddTransitEntitiesToTimetable.java index 8342e96f9eb..27c23db83d8 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/AddTransitEntitiesToTimetable.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/AddTransitEntitiesToTimetable.java @@ -68,9 +68,7 @@ private void addTransfers(TransitRepository transitRepository) { private void addServices(TransitRepository transitRepository) { /* Assign 0-based numeric codes to all GTFS service IDs. */ for (FeedScopedId serviceId : dataImport.getAllServiceIds()) { - transitRepository - .getServiceCodes() - .put(serviceId, transitRepository.getServiceCodes().size()); + transitRepository.putServiceCode(serviceId, transitRepository.getServiceCodes().size()); } } diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModule.java b/application/src/main/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModule.java index f6c88fbaaf6..7fb9ed27697 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModule.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModule.java @@ -192,13 +192,11 @@ private boolean connectVertexToWay(TransitStopVertex ts, RegularStop stop, Graph var nearbyEdges = new HashMap>(); for (var edge : graph.findEdges(getEnvelope(ts))) { - osmInfoGraphBuildService - .findPlatform(edge) - .ifPresent(platform -> { - if (matchesReference(stop, platform.references())) { - nearbyEdges.computeIfAbsent(platform, _ -> new ArrayList<>()).add(edge); - } - }); + osmInfoGraphBuildService.findPlatform(edge).ifPresent(platform -> { + if (matchesReference(stop, platform.references())) { + nearbyEdges.computeIfAbsent(platform, _ -> new ArrayList<>()).add(edge); + } + }); } return nearbyEdges diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/TimeZoneAdjusterModule.java b/application/src/main/java/org/opentripplanner/graph_builder/module/TimeZoneAdjusterModule.java index 59a34cdef64..7c100a86d37 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/TimeZoneAdjusterModule.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/TimeZoneAdjusterModule.java @@ -33,26 +33,24 @@ public void buildGraph() { Map agencyShift = new HashMap<>(); - transitRepository - .getAllTripPatterns() - .forEach(pattern -> { - var timeShift = agencyShift.computeIfAbsent( - pattern.getRoute().getAgency().getTimezone(), - zoneId -> - (graphOffset.minusSeconds(zoneId.getRules().getOffset(serviceStart).getTotalSeconds())) - ); - - if (timeShift.isZero()) { - return; - } - - TripPattern updatedPattern = pattern - .copy() - .withScheduledTimeTableBuilder(builder -> builder.withAdjustedTimes(timeShift)) - .build(); - // replace the original pattern with the updated pattern in the transit model - transitRepository.addTripPattern(updatedPattern.getId(), updatedPattern); - }); + transitRepository.getAllTripPatterns().forEach(pattern -> { + var timeShift = agencyShift.computeIfAbsent( + pattern.getRoute().getAgency().getTimezone(), + zoneId -> + graphOffset.minusSeconds(zoneId.getRules().getOffset(serviceStart).getTotalSeconds()) + ); + + if (timeShift.isZero()) { + return; + } + + TripPattern updatedPattern = pattern + .copy() + .withScheduledTimeTableBuilder(builder -> builder.withAdjustedTimes(timeShift)) + .build(); + // replace the original pattern with the updated pattern in the transit model + transitRepository.addTripPattern(updatedPattern.getId(), updatedPattern); + }); transitRepository.index(); } } diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/TripPatternNamer.java b/application/src/main/java/org/opentripplanner/graph_builder/module/TripPatternNamer.java index 8e88fe7081e..e621b62e9fc 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/TripPatternNamer.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/TripPatternNamer.java @@ -100,9 +100,8 @@ public static void generateUniqueNames(Collection tableTripPatterns for (TripPattern pattern : routeTripPatterns) { StopLocation start = pattern.firstStop(); StopLocation end = pattern.lastStop(); - String headsign = pattern.getTripHeadsign() != null - ? pattern.getTripHeadsign().toString() - : null; + String headsign = + pattern.getTripHeadsign() != null ? pattern.getTripHeadsign().toString() : null; if (headsign != null) { signs.put(headsign, pattern); } @@ -117,9 +116,8 @@ public static void generateUniqueNames(Collection tableTripPatterns continue; } StringBuilder sb = new StringBuilder(routeName); - String headsign = pattern.getTripHeadsign() != null - ? pattern.getTripHeadsign().toString() - : null; + String headsign = + pattern.getTripHeadsign() != null ? pattern.getTripHeadsign().toString() : null; if (headsign != null && signs.get(headsign).size() == 1) { pattern.initName(sb.append(" ").append(headsign).toString()); continue; @@ -138,7 +136,7 @@ public static void generateUniqueNames(Collection tableTripPatterns var start = pattern.firstStop(); sb.append(" from ").append(stopNameAndId(start)); if (starts.get(start).size() == 1) { - pattern.initName((sb.toString())); + pattern.initName(sb.toString()); // only pattern with this first stop continue; } @@ -149,7 +147,7 @@ public static void generateUniqueNames(Collection tableTripPatterns // set intersection remainingPatterns.retainAll(ends.get(end)); if (remainingPatterns.size() == 1) { - pattern.initName((sb.toString())); + pattern.initName(sb.toString()); continue; } @@ -162,7 +160,7 @@ public static void generateUniqueNames(Collection tableTripPatterns intersection.retainAll(vias.get(via)); if (intersection.size() == 1) { sb.append(" via ").append(stopNameAndId(via)); - pattern.initName((sb.toString())); + pattern.initName(sb.toString()); continue PATTERN; } } @@ -179,7 +177,7 @@ public static void generateUniqueNames(Collection tableTripPatterns .map(TripTimes::getTrip) .ifPresent(value -> sb.append(" like trip ").append(value.getId())); } - pattern.initName((sb.toString())); + pattern.initName(sb.toString()); } } diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/ValidateAndInterpolateStopTimesForEachTrip.java b/application/src/main/java/org/opentripplanner/graph_builder/module/ValidateAndInterpolateStopTimesForEachTrip.java index b071b21327b..bd46337e9ab 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/ValidateAndInterpolateStopTimesForEachTrip.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/ValidateAndInterpolateStopTimesForEachTrip.java @@ -210,8 +210,7 @@ private double getMaxSpeedForMode(TransitMode mode) { case CABLE_CAR -> 30; case GONDOLA, FUNICULAR -> 50; default -> 200; - } / - 3.6 + } / 3.6 ); } diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderModules.java b/application/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderModules.java index 372f4903882..03cf9d5e80e 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderModules.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderModules.java @@ -31,12 +31,12 @@ import org.opentripplanner.graph_builder.module.ned.GeotiffGridCoverageFactoryImpl; import org.opentripplanner.graph_builder.module.ned.NEDGridCoverageFactoryImpl; import org.opentripplanner.graph_builder.module.ned.parameter.DemExtractParameters; +import org.opentripplanner.graph_builder.module.osm.EdgeNamer; import org.opentripplanner.graph_builder.module.osm.OsmModule; import org.opentripplanner.graph_builder.module.osm.parameters.OsmExtractParameters; import org.opentripplanner.graph_builder.module.stopconnectivity.StopConnectivityModule; import org.opentripplanner.graph_builder.module.transfer.DirectTransferGenerator; import org.opentripplanner.graph_builder.services.ned.ElevationGridCoverageFactory; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer; import org.opentripplanner.gtfs.graphbuilder.GtfsBundle; import org.opentripplanner.gtfs.graphbuilder.GtfsModule; import org.opentripplanner.netex.NetexModule; @@ -86,9 +86,7 @@ static OsmModule provideOsmModule( GraphBuildCacheManager cacheManager ) { List providers = new ArrayList<>(); - for (ConfiguredDataSource< - OsmExtractParameters - > osmConfiguredDataSource : dataSources.getOsmConfiguredDataSource()) { + for (ConfiguredDataSource osmConfiguredDataSource : dataSources.getOsmConfiguredDataSource()) { providers.add( new DefaultOsmProvider( osmConfiguredDataSource.dataSource(), @@ -115,6 +113,7 @@ static OsmModule provideOsmModule( .withIncludeInclinedEdgeLevelInfo(config.includeInclinedEdgeLevelInfo) .withMaxAreaNodes(config.maxAreaNodes) .withBoardingAreaRefTags(config.boardingLocationTags) + .withElevatorRefTags(config.elevatorRefTags) .withIncludeOsmStationEntrances(config.osmDefaults.includeOsmStationEntrances()) .withCacheManager(cacheManager) .withIssueStore(issueStore) diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/geometry/GeometryProcessor.java b/application/src/main/java/org/opentripplanner/graph_builder/module/geometry/GeometryProcessor.java index dd54d24e469..e57b6c13059 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/geometry/GeometryProcessor.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/geometry/GeometryProcessor.java @@ -61,9 +61,8 @@ public GeometryProcessor( DataImportIssueStore issueStore ) { this.builder = builder; - this.maxStopToShapeSnapDistance = maxStopToShapeSnapDistance > 0 - ? maxStopToShapeSnapDistance - : 150; + this.maxStopToShapeSnapDistance = + maxStopToShapeSnapDistance > 0 ? maxStopToShapeSnapDistance : 150; this.issueStore = issueStore; } @@ -383,10 +382,8 @@ private List getStopLocations( } // we found one! // best match may be the split segment with the previous stop, in this case we need to load the full segment - IndexedLineSegment matchedSegment = prevSegment != null && - bestMatch.index == prevSegment.index - ? prevSegment - : bestMatch; + IndexedLineSegment matchedSegment = + prevSegment != null && bestMatch.index == prevSegment.index ? prevSegment : bestMatch; prevSegmentFraction = matchedSegment.fraction(stopCoord); LinearLocation location = new LinearLocation(0, bestMatch.index, prevSegmentFraction); locations.add(location); diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/geometry/ShapeSegmentKey.java b/application/src/main/java/org/opentripplanner/graph_builder/module/geometry/ShapeSegmentKey.java index 097ad9d17ea..7e2e06c62d9 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/geometry/ShapeSegmentKey.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/geometry/ShapeSegmentKey.java @@ -25,7 +25,7 @@ public int hashCode() { result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(shapeDistanceTo); result = prime * result + (int) (temp ^ (temp >>> 32)); - result = prime * result + ((shapeId == null) ? 0 : shapeId.hashCode()); + result = prime * result + (shapeId == null ? 0 : shapeId.hashCode()); return result; } diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningModule.java b/application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningModule.java index 5efc7a95ae2..8b7e6888f4e 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningModule.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningModule.java @@ -95,11 +95,10 @@ public void buildGraph() { // note that visibility vertices must not be removed from the graph // because serialization will break. Edge lists are reconstructed // only for graph vertices after loading the graph - List areaEdges = graph.getEdgesOfType(AreaEdge.class); HashSet areas = new HashSet<>(); HashSet visibilityVertices = new HashSet<>(); - for (AreaEdge ae : areaEdges) { + for (AreaEdge ae : graph.findEdges(AreaEdge.class)) { areas.add(ae.getArea()); } for (AreaGroup a : areas) { @@ -217,10 +216,11 @@ private int processIslands( int pruningThresholdWithStops = parameters.pruningThresholdIslandWithStops(); // do not remove real islands which have only ferry stops if (!onlyFerry && island.streetSize() < pruningThresholdWithStops * adaptivePruningFactor) { - double sizeCoeff = (adaptivePruningFactor > 1.0) - ? island.distanceFromOtherGraph(graph, adaptivePruningDistance) / - adaptivePruningDistance - : 1.0; + double sizeCoeff = + adaptivePruningFactor > 1.0 + ? island.distanceFromOtherGraph(graph, adaptivePruningDistance) / + adaptivePruningDistance + : 1.0; if (island.streetSize() * sizeCoeff < pruningThresholdWithStops) { if (restrictOrRemove(island, isolated, stats, markIsolated, traverseMode)) { @@ -233,10 +233,11 @@ private int processIslands( //for islands without stops int pruningThresholdWithoutStops = parameters.pruningThresholdIslandWithoutStops(); if (island.streetSize() < pruningThresholdWithoutStops * adaptivePruningFactor) { - double sizeCoeff = (adaptivePruningFactor > 1.0) - ? island.distanceFromOtherGraph(graph, adaptivePruningDistance) / - adaptivePruningDistance - : 1.0; + double sizeCoeff = + adaptivePruningFactor > 1.0 + ? island.distanceFromOtherGraph(graph, adaptivePruningDistance) / + adaptivePruningDistance + : 1.0; if (island.streetSize() * sizeCoeff < pruningThresholdWithoutStops) { if (restrictOrRemove(island, isolated, stats, markIsolated, traverseMode)) { stats.incrementModifiedIslands(); diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/Subgraph.java b/application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/Subgraph.java index 3eda43b16f1..e8c55cf20be 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/Subgraph.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/Subgraph.java @@ -36,7 +36,7 @@ void addVertex(Vertex vertex) { } boolean contains(Vertex vertex) { - return (streetVertices.contains(vertex) || stopVertices.contains(vertex)); + return streetVertices.contains(vertex) || stopVertices.contains(vertex); } int streetSize() { diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/ned/ElevationModule.java b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/ElevationModule.java index 5d28ad1d47a..4d3670ac8cf 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/ned/ElevationModule.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/ElevationModule.java @@ -323,9 +323,8 @@ private Map collectKnownElevationsForVertices( ) { // knownElevations will be null if there are no ElevationPoints in the data // for instance, with the Shapefile loader.) - var elevations = knownElevations != null - ? new HashMap<>(knownElevations) - : new HashMap(); + var elevations = + knownElevations != null ? new HashMap<>(knownElevations) : new HashMap(); // If including the EllipsoidToGeoidDifference, subtract these from the known elevations // found in OpenStreetMap data. @@ -444,7 +443,7 @@ private void processEdge(StreetEdge ee) { sampleDistance, getElevation( coverage, - new Coordinate(x1 + (pctAlongSeg * (x2 - x1)), y1 + (pctAlongSeg * (y2 - y1))) + new Coordinate(x1 + pctAlongSeg * (x2 - x1), y1 + pctAlongSeg * (y2 - y1)) ) ) ); @@ -586,7 +585,7 @@ private double getElevation(Coverage coverage, double x, double y) } var elevation = - (values[0] * gridCoverageFactory.elevationUnitMultiplier()) - + values[0] * gridCoverageFactory.elevationUnitMultiplier() - (includeEllipsoidToGeoidDifference ? getApproximateEllipsoidToGeoidDifference(y, x) : 0); minElevation = Math.min(minElevation, elevation); diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/ned/MissingElevationHandler.java b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/MissingElevationHandler.java index a08ce522259..426b7a880b9 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/ned/MissingElevationHandler.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/MissingElevationHandler.java @@ -82,56 +82,48 @@ void run() { propagateElevationToNearbyVertices(pq, elevations); // Assign elevations to street edges based on the vertices - elevations - .keySet() - .forEach(vertex -> { - vertex - .getIncomingStreetEdges() - .forEach(edge -> assignElevationToEdgeIfPossible(elevations, edge)); - vertex - .getOutgoingStreetEdges() - .forEach(edge -> assignElevationToEdgeIfPossible(elevations, edge)); - }); + elevations.keySet().forEach(vertex -> { + vertex + .getIncomingStreetEdges() + .forEach(edge -> assignElevationToEdgeIfPossible(elevations, edge)); + vertex + .getOutgoingStreetEdges() + .forEach(edge -> assignElevationToEdgeIfPossible(elevations, edge)); + }); } private BinHeap createPriorityQueue(Map elevations) { var pq = new BinHeap(); - elevations.forEach( - ((vertex, elevation) -> { - vertex - .getIncoming() - .forEach(edge -> { - if (edge.getDistanceMeters() < maxElevationPropagationMeters) { - pq.insert( - new ElevationRepairState( - vertex, - elevation, - edge.getFromVertex(), - edge.getDistanceMeters() - ), - edge.getDistanceMeters() - ); - } - }); - - vertex - .getOutgoing() - .forEach(edge -> { - if (edge.getDistanceMeters() < maxElevationPropagationMeters) { - pq.insert( - new ElevationRepairState( - vertex, - elevation, - edge.getToVertex(), - edge.getDistanceMeters() - ), - edge.getDistanceMeters() - ); - } - }); - }) - ); + elevations.forEach((vertex, elevation) -> { + vertex.getIncoming().forEach(edge -> { + if (edge.getDistanceMeters() < maxElevationPropagationMeters) { + pq.insert( + new ElevationRepairState( + vertex, + elevation, + edge.getFromVertex(), + edge.getDistanceMeters() + ), + edge.getDistanceMeters() + ); + } + }); + + vertex.getOutgoing().forEach(edge -> { + if (edge.getDistanceMeters() < maxElevationPropagationMeters) { + pq.insert( + new ElevationRepairState( + vertex, + elevation, + edge.getToVertex(), + edge.getDistanceMeters() + ), + edge.getDistanceMeters() + ); + } + }); + }); return pq; } diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/ned/parameter/DemExtractParameters.java b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/parameter/DemExtractParameters.java index caa07974f92..8fc7d5f1a36 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/ned/parameter/DemExtractParameters.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/parameter/DemExtractParameters.java @@ -7,8 +7,10 @@ * Configuration of a DEM extract. Example: * {@code "dem" : [ {source: "file:///path/to/otp/norway-dem.tif"} ] } */ -public record DemExtractParameters(URI source, Double elevationUnitMultiplier) implements - DataSourceConfig { +public record DemExtractParameters( + URI source, + Double elevationUnitMultiplier +) implements DataSourceConfig { public static final double DEFAULT_ELEVATION_UNIT_MULTIPLIER = 1; public static final DemExtractParameters DEFAULT = new DemExtractParametersBuilder().build(); diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/BarrierEdgeBuilder.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/BarrierEdgeBuilder.java index cd087af40fa..2aa1b66c452 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/BarrierEdgeBuilder.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/BarrierEdgeBuilder.java @@ -6,7 +6,6 @@ import java.util.Collection; import java.util.List; import org.opentripplanner.core.model.i18n.I18NString; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer; import org.opentripplanner.osm.model.OsmNode; import org.opentripplanner.osm.model.OsmWay; import org.opentripplanner.street.geometry.GeometryUtils; @@ -15,11 +14,11 @@ import org.opentripplanner.street.model.vertex.OsmVertex; import org.opentripplanner.street.model.vertex.Vertex; -public class BarrierEdgeBuilder { +class BarrierEdgeBuilder { private final EdgeNamer edgeNamer; - public BarrierEdgeBuilder(EdgeNamer edgeNamer) { + BarrierEdgeBuilder(EdgeNamer edgeNamer) { this.edgeNamer = edgeNamer; } @@ -55,8 +54,12 @@ public void build(OsmNode node, Collection vertices, Collection ways) { >(); TLongObjectMap index = new TLongObjectHashMap<>(ways.size()); var synchronizedIndex = TCollections.synchronizedMap(index); - ways - .parallelStream() - .forEach(way -> { - var props = way.getOsmProvider().getWayPropertySet().getDataForWay(way); - var canonicalProps = distinctProps.computeIfAbsent(props, p -> p); - synchronizedIndex.put(way.getId(), canonicalProps); - //Keep lambda! A method-ref would log incorrect class and line number - //noinspection Convert2MethodRef - progress.step(m -> LOG.info(m)); - }); + ways.parallelStream().forEach(way -> { + var props = way.getOsmProvider().getWayPropertySet().getDataForWay(way); + var canonicalProps = distinctProps.computeIfAbsent(props, p -> p); + synchronizedIndex.put(way.getId(), canonicalProps); + //Keep lambda! A method-ref would log incorrect class and line number + //noinspection Convert2MethodRef + progress.step(m -> LOG.info(m)); + }); LOG.info(progress.completeMessage()); return new BidirectionalWayPropertiesIndex(index); diff --git a/application/src/main/java/org/opentripplanner/graph_builder/services/osm/EdgeNamer.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/EdgeNamer.java similarity index 85% rename from application/src/main/java/org/opentripplanner/graph_builder/services/osm/EdgeNamer.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/EdgeNamer.java index 32fc64ebdec..7e38785de43 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/services/osm/EdgeNamer.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/EdgeNamer.java @@ -1,9 +1,9 @@ -package org.opentripplanner.graph_builder.services.osm; +package org.opentripplanner.graph_builder.module.osm; import java.util.Optional; import org.opentripplanner.core.model.i18n.I18NString; -import org.opentripplanner.graph_builder.module.osm.OsmDatabase; -import org.opentripplanner.graph_builder.module.osm.StreetEdgePair; +import org.opentripplanner.graph_builder.module.osm.model.StreetEdgePair; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; import org.opentripplanner.osm.model.OsmEntity; import org.opentripplanner.osm.model.OsmWay; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ElevatorProcessor.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ElevatorProcessor.java index 5683b911292..7043d42cd98 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ElevatorProcessor.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ElevatorProcessor.java @@ -17,6 +17,10 @@ import org.opentripplanner.graph_builder.issues.FewerThanTwoIntersectionNodesInElevatorWay; import org.opentripplanner.graph_builder.issues.MoreThanTwoIntersectionNodesInElevatorWay; import org.opentripplanner.graph_builder.issues.OnlyOneConnectionToElevatorNode; +import org.opentripplanner.graph_builder.module.osm.model.OsmElevatorKey; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; +import org.opentripplanner.graph_builder.module.osm.storage.VertexGenerator; +import org.opentripplanner.osm.model.CompoundRefTagGroup; import org.opentripplanner.osm.model.OsmLevel; import org.opentripplanner.osm.model.OsmLevelFactory; import org.opentripplanner.osm.model.OsmLevelSource; @@ -97,13 +101,15 @@ class ElevatorProcessor { private final Consumer osmEntityDurationIssueConsumer; private final DataImportIssueStore issueStore; private final StreetDetailsRepository streetDetailsRepository; + private final List elevatorRefTags; public ElevatorProcessor( DataImportIssueStore issueStore, OsmDatabase osmdb, VertexGenerator vertexGenerator, Graph graph, - StreetDetailsRepository streetDetailsRepository + StreetDetailsRepository streetDetailsRepository, + List elevatorRefTags ) { this.osmdb = osmdb; this.vertexGenerator = vertexGenerator; @@ -118,6 +124,7 @@ public ElevatorProcessor( ); this.issueStore = issueStore; this.streetDetailsRepository = streetDetailsRepository; + this.elevatorRefTags = elevatorRefTags; } /** @@ -151,8 +158,7 @@ private void buildElevatorEdgesFromElevatorNodes() { .stream() .map(key -> verticeLevels.get(key)) .distinct() - .count() == - 1 + .count() == 1 ) { issueStore.add(new AllWaysOfElevatorNodeOnSameLevel(node)); } @@ -187,7 +193,8 @@ private void buildElevatorEdgesFromElevatorNodes() { .toList(), wheelchair, !node.isBicycleDenied(), - (int) travelTime + (int) travelTime, + node.getCompoundTagValue(elevatorRefTags).orElse(null) ); LOG.debug("Created elevator edges for node {}", node.getId()); } @@ -272,7 +279,8 @@ private void buildElevatorEdgesFromElevatorWays() { nodeLevels, wheelchair, !way.isBicycleDenied(), - (int) travelTime + (int) travelTime, + way.getCompoundTagValue(elevatorRefTags).orElse(null) ); LOG.debug("Created elevator edges for way {}", way.getId()); } @@ -310,7 +318,8 @@ private static void createElevatorHopEdges( List elevatorHopVertexLevels, Accessibility wheelchair, boolean bicycleAllowed, - int travelTime + int travelTime, + String id ) { // -1 because we loop over elevatorHopVertices two at a time for (int i = 0, vSize = elevatorHopVertices.size() - 1; i < vSize; i++) { @@ -330,7 +339,8 @@ private static void createElevatorHopEdges( permission, wheelchair, Math.abs(toLevel.level() - fromLevel.level()), - travelTime + travelTime, + id ); } } diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorProcessor.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorProcessor.java index 8dd1e786979..c2a44c9cfe0 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorProcessor.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorProcessor.java @@ -4,6 +4,7 @@ import java.util.Optional; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issue.api.Issue; +import org.opentripplanner.graph_builder.module.osm.model.EscalatorEdgePair; import org.opentripplanner.osm.model.OsmWay; import org.opentripplanner.street.model.edge.EscalatorEdge; import org.opentripplanner.street.model.vertex.IntersectionVertex; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/edgelevelinfo/InclinedEdgeLevelInfoProcessor.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/InclinedEdgeLevelInfoProcessor.java similarity index 82% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/edgelevelinfo/InclinedEdgeLevelInfoProcessor.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/InclinedEdgeLevelInfoProcessor.java index 5d19cf3b2c8..2125f6ec003 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/edgelevelinfo/InclinedEdgeLevelInfoProcessor.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/InclinedEdgeLevelInfoProcessor.java @@ -1,7 +1,8 @@ -package org.opentripplanner.graph_builder.module.osm.edgelevelinfo; +package org.opentripplanner.graph_builder.module.osm; import java.util.Optional; import javax.annotation.Nullable; +import org.opentripplanner.graph_builder.module.osm.internal.edgelevelinfo.NoopInclinedEdgeLevelInfoProcessor; import org.opentripplanner.osm.model.OsmWay; import org.opentripplanner.service.streetdetails.StreetDetailsRepository; import org.opentripplanner.service.streetdetails.model.InclinedEdgeLevelInfo; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmElevatorKey.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmElevatorKey.java deleted file mode 100644 index 0b9a84a1a87..00000000000 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmElevatorKey.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.opentripplanner.graph_builder.module.osm; - -import org.opentripplanner.street.model.vertex.OsmEntityType; - -record OsmElevatorKey(long nodeId, OsmEntityType osmEntityType, long entityId) {} diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java index 6d88adbd162..aecc3038444 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java @@ -1,7 +1,7 @@ package org.opentripplanner.graph_builder.module.osm; -import static org.opentripplanner.graph_builder.module.osm.LinearBarrierNodeType.NORMAL; -import static org.opentripplanner.graph_builder.module.osm.LinearBarrierNodeType.SPLIT; +import static org.opentripplanner.graph_builder.module.osm.model.LinearBarrierNodeType.NORMAL; +import static org.opentripplanner.graph_builder.module.osm.model.LinearBarrierNodeType.SPLIT; import static org.opentripplanner.osm.model.TraverseDirection.BACKWARD; import static org.opentripplanner.osm.model.TraverseDirection.DIRECTIONLESS; import static org.opentripplanner.osm.model.TraverseDirection.FORWARD; @@ -27,9 +27,17 @@ import org.opentripplanner.graph_builder.module.cache.CacheTask; import org.opentripplanner.graph_builder.module.cache.GraphBuildCacheManager; import org.opentripplanner.graph_builder.module.cache.KeyValueCache; -import org.opentripplanner.graph_builder.module.osm.edgelevelinfo.DefaultInclinedEdgeLevelInfoProcessor; -import org.opentripplanner.graph_builder.module.osm.edgelevelinfo.NoopInclinedEdgeLevelInfoProcessor; +import org.opentripplanner.graph_builder.module.osm.internal.edgelevelinfo.DefaultInclinedEdgeLevelInfoProcessor; +import org.opentripplanner.graph_builder.module.osm.internal.edgelevelinfo.NoopInclinedEdgeLevelInfoProcessor; +import org.opentripplanner.graph_builder.module.osm.internal.walkablearea.WalkableAreaBuilder; +import org.opentripplanner.graph_builder.module.osm.model.EscalatorEdgePair; +import org.opentripplanner.graph_builder.module.osm.model.OsmArea; +import org.opentripplanner.graph_builder.module.osm.model.OsmAreaGroup; +import org.opentripplanner.graph_builder.module.osm.model.StreetEdgePair; +import org.opentripplanner.graph_builder.module.osm.model.TurnRestrictionTag; import org.opentripplanner.graph_builder.module.osm.parameters.OsmProcessingParameters; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; +import org.opentripplanner.graph_builder.module.osm.storage.VertexGenerator; import org.opentripplanner.osm.OsmProvider; import org.opentripplanner.osm.model.OsmLevel; import org.opentripplanner.osm.model.OsmNode; @@ -200,7 +208,8 @@ private void build(OsmDatabase osmdb, VertexGenerator vertexGenerator) { osmdb, vertexGenerator, graph, - streetDetailsRepository + streetDetailsRepository, + params.elevatorRefTags() ); buildBasicGraph(osmdb, vertexGenerator, elevatorProcessor); @@ -736,12 +745,10 @@ private StreetEdge getEdgeForStreet( private float getMaxCarSpeed() { float maxSpeed = 0f; - for (var e : graph.getEdges()) { - if (e instanceof StreetEdge se) { - var carSpeed = se.getCarSpeed(); - if (carSpeed > maxSpeed) { - maxSpeed = carSpeed; - } + for (var se : graph.findEdges(StreetEdge.class)) { + var carSpeed = se.getCarSpeed(); + if (carSpeed > maxSpeed) { + maxSpeed = carSpeed; } } return maxSpeed; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModuleBuilder.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModuleBuilder.java index 3a0136896c6..51ebc23a1da 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModuleBuilder.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModuleBuilder.java @@ -1,13 +1,14 @@ package org.opentripplanner.graph_builder.module.osm; import java.util.Collection; +import java.util.List; import java.util.Set; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.module.cache.GraphBuildCacheManager; +import org.opentripplanner.graph_builder.module.osm.internal.naming.DefaultNamer; import org.opentripplanner.graph_builder.module.osm.parameters.OsmProcessingParameters; -import org.opentripplanner.graph_builder.services.osm.DefaultNamer; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer; import org.opentripplanner.osm.OsmProvider; +import org.opentripplanner.osm.model.CompoundRefTagGroup; import org.opentripplanner.service.osminfo.OsmInfoGraphBuildRepository; import org.opentripplanner.service.streetdetails.StreetDetailsRepository; import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; @@ -28,6 +29,7 @@ public class OsmModuleBuilder { private final OsmInfoGraphBuildRepository osmInfoGraphBuildRepository; private Set boardingAreaRefTags = Set.of(); + private List elevatorRefTags = List.of(); private DataImportIssueStore issueStore = DataImportIssueStore.NOOP; private EdgeNamer edgeNamer = new DefaultNamer(); private boolean areaVisibility = false; @@ -61,6 +63,11 @@ public OsmModuleBuilder withBoardingAreaRefTags(Set boardingAreaRefTags) return this; } + public OsmModuleBuilder withElevatorRefTags(List elevatorRefTags) { + this.elevatorRefTags = elevatorRefTags; + return this; + } + public OsmModuleBuilder withIssueStore(DataImportIssueStore issueStore) { this.issueStore = issueStore; return this; @@ -122,6 +129,7 @@ public OsmModule build() { issueStore, new OsmProcessingParameters( boardingAreaRefTags, + elevatorRefTags, edgeNamer, maxAreaNodes, areaVisibility, diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessor.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessor.java index 70b3bac3cea..72db1657c80 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessor.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessor.java @@ -21,6 +21,9 @@ import org.opentripplanner.graph_builder.issues.InvalidVehicleParkingCapacity; import org.opentripplanner.graph_builder.issues.IsolatedParkAndRide; import org.opentripplanner.graph_builder.issues.ParkAndRideWalkAccessibilityMismatch; +import org.opentripplanner.graph_builder.module.osm.model.OsmArea; +import org.opentripplanner.graph_builder.module.osm.model.OsmAreaGroup; +import org.opentripplanner.graph_builder.module.osm.model.Ring; import org.opentripplanner.osm.OsmOpeningHoursParser; import org.opentripplanner.osm.model.OsmEntity; import org.opentripplanner.osm.model.OsmNode; @@ -384,9 +387,7 @@ private OptionalInt parseCapacity(OsmEntity element, String capacityTag) { ); } - private List< - VehicleParking.VehicleParkingEntranceCreator - > createParkingEntrancesFromAccessVertices( + private List createParkingEntrancesFromAccessVertices( Set accessVertices, I18NString vehicleParkingName, OsmEntity entity diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/SafetyValueApplier.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/SafetyValueApplier.java index bedfa937a00..85f80cb0043 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/SafetyValueApplier.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/SafetyValueApplier.java @@ -1,13 +1,11 @@ package org.opentripplanner.graph_builder.module.osm; -import java.util.Set; import javax.annotation.Nullable; import org.opentripplanner.osm.model.OsmEntity; import org.opentripplanner.osm.tagmapping.OsmTagMapper; import org.opentripplanner.osm.wayproperty.WayProperties; import org.opentripplanner.street.graph.Graph; import org.opentripplanner.street.model.edge.StreetEdge; -import org.opentripplanner.street.model.note.StreetNoteAndMatcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,7 +15,7 @@ * provide a {@link org.opentripplanner.astar.spi.RemainingWeightHeuristic} * that incorporates walk and bike safety in its lower bound. */ -class SafetyValueApplier { +public class SafetyValueApplier { private static final Logger LOG = LoggerFactory.getLogger(SafetyValueApplier.class); @@ -32,7 +30,7 @@ class SafetyValueApplier { */ private float bestWalkSafety = 1.0f; - SafetyValueApplier(Graph graph) { + public SafetyValueApplier(Graph graph) { this.graph = graph; } @@ -56,7 +54,7 @@ float getBestWalkSafety() { return bestWalkSafety; } - void applyWayProperties( + public void applyWayProperties( @Nullable StreetEdge street, @Nullable StreetEdge backStreet, WayProperties forwardWayData, @@ -65,8 +63,6 @@ void applyWayProperties( ) { OsmTagMapper tagMapperForWay = way.getOsmProvider().getOsmTagMapper(); - Set notes = way.getOsmProvider().getWayPropertySet().getNoteForWay(way); - boolean motorVehicleNoThrough = tagMapperForWay.isMotorVehicleThroughTrafficExplicitlyDisallowed(way); boolean bicycleNoThrough = tagMapperForWay.isBicycleThroughTrafficExplicitlyDisallowed(way); @@ -93,11 +89,6 @@ void applyWayProperties( street ); } - if (notes != null) { - for (var it : notes) { - graph.streetNotesService.addStaticNote(street, it.note(), it.matcher()); - } - } street.setMotorVehicleNoThruTraffic(motorVehicleNoThrough); street.setBicycleNoThruTraffic(bicycleNoThrough); street.setWalkNoThruTraffic(walkNoThrough); @@ -124,11 +115,6 @@ void applyWayProperties( ); } backStreet.setWalkSafetyFactor((float) walkSafety); - if (notes != null) { - for (var it : notes) { - graph.streetNotesService.addStaticNote(backStreet, it.note(), it.matcher()); - } - } backStreet.setMotorVehicleNoThruTraffic(motorVehicleNoThrough); backStreet.setBicycleNoThruTraffic(bicycleNoThrough); backStreet.setWalkNoThruTraffic(walkNoThrough); diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/StreetTraversalPermissionPair.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/StreetTraversalPermissionPair.java deleted file mode 100644 index 4036ee7fa0d..00000000000 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/StreetTraversalPermissionPair.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.opentripplanner.graph_builder.module.osm; - -import org.opentripplanner.street.model.StreetTraversalPermission; - -public record StreetTraversalPermissionPair( - StreetTraversalPermission main, - StreetTraversalPermission back -) {} diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionUnifier.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionUnifier.java index d3c3158b6c4..00a205cb357 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionUnifier.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionUnifier.java @@ -4,6 +4,8 @@ import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issues.TurnRestrictionBad; +import org.opentripplanner.graph_builder.module.osm.model.TurnRestrictionTag; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; import org.opentripplanner.service.osminfo.OsmInfoGraphBuildRepository; import org.opentripplanner.street.model.TurnRestriction; import org.opentripplanner.street.model.edge.StreetEdge; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/edgelevelinfo/DefaultInclinedEdgeLevelInfoProcessor.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/internal/edgelevelinfo/DefaultInclinedEdgeLevelInfoProcessor.java similarity index 95% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/edgelevelinfo/DefaultInclinedEdgeLevelInfoProcessor.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/internal/edgelevelinfo/DefaultInclinedEdgeLevelInfoProcessor.java index cc3f4acf9cb..0075a634107 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/edgelevelinfo/DefaultInclinedEdgeLevelInfoProcessor.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/internal/edgelevelinfo/DefaultInclinedEdgeLevelInfoProcessor.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm.edgelevelinfo; +package org.opentripplanner.graph_builder.module.osm.internal.edgelevelinfo; import java.util.List; import java.util.Optional; @@ -6,7 +6,8 @@ import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issues.ContradictoryLevelAndInclineInfoForWay; import org.opentripplanner.graph_builder.issues.CouldNotApplyMultiLevelInfoToWay; -import org.opentripplanner.graph_builder.module.osm.OsmDatabase; +import org.opentripplanner.graph_builder.module.osm.InclinedEdgeLevelInfoProcessor; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; import org.opentripplanner.osm.model.OsmLevel; import org.opentripplanner.osm.model.OsmWay; import org.opentripplanner.service.streetdetails.StreetDetailsRepository; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/edgelevelinfo/NoopInclinedEdgeLevelInfoProcessor.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/internal/edgelevelinfo/NoopInclinedEdgeLevelInfoProcessor.java similarity index 80% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/edgelevelinfo/NoopInclinedEdgeLevelInfoProcessor.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/internal/edgelevelinfo/NoopInclinedEdgeLevelInfoProcessor.java index 3adc32bb7e4..e5fa33524cb 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/edgelevelinfo/NoopInclinedEdgeLevelInfoProcessor.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/internal/edgelevelinfo/NoopInclinedEdgeLevelInfoProcessor.java @@ -1,7 +1,8 @@ -package org.opentripplanner.graph_builder.module.osm.edgelevelinfo; +package org.opentripplanner.graph_builder.module.osm.internal.edgelevelinfo; import java.util.Optional; import javax.annotation.Nullable; +import org.opentripplanner.graph_builder.module.osm.InclinedEdgeLevelInfoProcessor; import org.opentripplanner.osm.model.OsmWay; import org.opentripplanner.service.streetdetails.model.InclinedEdgeLevelInfo; import org.opentripplanner.street.model.edge.Edge; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/services/osm/DefaultNamer.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/internal/naming/DefaultNamer.java similarity index 61% rename from application/src/main/java/org/opentripplanner/graph_builder/services/osm/DefaultNamer.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/internal/naming/DefaultNamer.java index 96b4b87b2c9..944802ed428 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/services/osm/DefaultNamer.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/internal/naming/DefaultNamer.java @@ -1,8 +1,9 @@ -package org.opentripplanner.graph_builder.services.osm; +package org.opentripplanner.graph_builder.module.osm.internal.naming; import org.opentripplanner.core.model.i18n.I18NString; -import org.opentripplanner.graph_builder.module.osm.OsmDatabase; -import org.opentripplanner.graph_builder.module.osm.StreetEdgePair; +import org.opentripplanner.graph_builder.module.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.model.StreetEdgePair; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; import org.opentripplanner.osm.model.OsmEntity; import org.opentripplanner.osm.model.OsmWay; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/PlatformEntranceFinder.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/PlatformEntranceFinder.java similarity index 97% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/PlatformEntranceFinder.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/PlatformEntranceFinder.java index 8d00db16ee2..781ba8dd0e0 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/PlatformEntranceFinder.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/PlatformEntranceFinder.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.internal.walkablearea; import java.util.Collection; import java.util.List; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilder.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/WalkableAreaBuilder.java similarity index 96% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilder.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/WalkableAreaBuilder.java index 329aecaba3a..bb6231596e7 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilder.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/WalkableAreaBuilder.java @@ -1,6 +1,6 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.internal.walkablearea; -import static org.opentripplanner.graph_builder.module.osm.LinearBarrierNodeType.SPLIT; +import static org.opentripplanner.graph_builder.module.osm.model.LinearBarrierNodeType.SPLIT; import java.util.ArrayList; import java.util.Collection; @@ -22,7 +22,15 @@ import org.opentripplanner.framework.application.OTPRequestTimeoutException; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.module.cache.KeyValueCache; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.SafetyValueApplier; +import org.opentripplanner.graph_builder.module.osm.issues.AreaTooComplicated; +import org.opentripplanner.graph_builder.module.osm.issues.UnconnectedArea; +import org.opentripplanner.graph_builder.module.osm.model.OsmArea; +import org.opentripplanner.graph_builder.module.osm.model.OsmAreaGroup; +import org.opentripplanner.graph_builder.module.osm.model.Ring; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; +import org.opentripplanner.graph_builder.module.osm.storage.VertexGenerator; import org.opentripplanner.osm.model.OsmEntity; import org.opentripplanner.osm.model.OsmNode; import org.opentripplanner.osm.model.OsmRelation; @@ -50,7 +58,7 @@ import org.opentripplanner.street.search.state.State; import org.opentripplanner.street.search.strategy.DominanceFunctions; -class WalkableAreaBuilder { +public class WalkableAreaBuilder { private final DataImportIssueStore issueStore; private final int maxAreaNodes; @@ -224,14 +232,12 @@ public void buildWithVisibility(OsmAreaGroup group) { if (visibilityCache != null) { double[][] pairs = surviving .stream() - .map(e -> - new double[] { - e.getFromVertex().getX(), - e.getFromVertex().getY(), - e.getToVertex().getX(), - e.getToVertex().getY(), - } - ) + .map(e -> new double[] { + e.getFromVertex().getX(), + e.getFromVertex().getY(), + e.getToVertex().getX(), + e.getToVertex().getY(), + }) .toArray(double[][]::new); visibilityCache.put(cacheKey, pairs); } diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/AreaTooComplicated.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/issues/AreaTooComplicated.java similarity index 75% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/AreaTooComplicated.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/issues/AreaTooComplicated.java index a139b5bbd15..864e46ccc05 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/AreaTooComplicated.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/issues/AreaTooComplicated.java @@ -1,11 +1,15 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.issues; import org.locationtech.jts.geom.Geometry; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; +import org.opentripplanner.graph_builder.module.osm.model.OsmAreaGroup; import org.opentripplanner.osm.model.OsmEntity; -public record AreaTooComplicated(OsmAreaGroup areaGroup, int nbNodes, int maxAreaNodes) implements - DataImportIssue { +public record AreaTooComplicated( + OsmAreaGroup areaGroup, + int nbNodes, + int maxAreaNodes +) implements DataImportIssue { private static final String FMT = "Area %s is too complicated (%s > %s)"; private static final String HTMLFMT = "Area '%s' is too complicated (%s > %s)"; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/UnconnectedArea.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/issues/UnconnectedArea.java similarity index 87% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/UnconnectedArea.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/issues/UnconnectedArea.java index 29c6d3c39d5..22f2a7f2d52 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/UnconnectedArea.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/issues/UnconnectedArea.java @@ -1,8 +1,9 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.issues; import java.util.stream.Collectors; import org.locationtech.jts.geom.Geometry; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; +import org.opentripplanner.graph_builder.module.osm.model.OsmAreaGroup; public record UnconnectedArea(OsmAreaGroup areaGroup) implements DataImportIssue { private static final String FMT = "Area %s has no connection to street network"; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/DisjointSet.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/DisjointSet.java similarity index 95% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/DisjointSet.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/DisjointSet.java index d130a435eaf..d5b524bd7b6 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/DisjointSet.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/DisjointSet.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.model; import gnu.trove.list.TIntList; import gnu.trove.list.array.TIntArrayList; @@ -12,7 +12,7 @@ import org.opentripplanner.framework.collection.TroveUtils; /** Basic union-find data structure with path compression */ -class DisjointSet { +public class DisjointSet { TIntList sets = new TIntArrayList(); diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorEdgePair.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/EscalatorEdgePair.java similarity index 76% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorEdgePair.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/EscalatorEdgePair.java index 3e4183ebcbc..b844e87d2cc 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorEdgePair.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/EscalatorEdgePair.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.model; import javax.annotation.Nullable; import org.opentripplanner.street.model.edge.EscalatorEdge; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/LinearBarrierNodeType.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/LinearBarrierNodeType.java similarity index 75% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/LinearBarrierNodeType.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/LinearBarrierNodeType.java index 15eac61cedc..c604970267a 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/LinearBarrierNodeType.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/LinearBarrierNodeType.java @@ -1,6 +1,6 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.model; -enum LinearBarrierNodeType { +public enum LinearBarrierNodeType { /** * Create a split vertex for the node on the linear barrier. Used when the barrier runs along * an area. diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmArea.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/OsmArea.java similarity index 96% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmArea.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/OsmArea.java index a6ab67f6e75..a20c30f56f6 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmArea.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/OsmArea.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.model; import com.google.common.collect.ArrayListMultimap; import gnu.trove.list.TLongList; @@ -25,14 +25,14 @@ * http://wiki.openstreetmap.org/wiki/Relation:multipolygon/Algorithm but generally done in a * quick/dirty way. */ -class OsmArea { +public class OsmArea { - final List outermostRings; + public final List outermostRings; // This is the way or relation that has the relevant tags for the area - final OsmEntity parent; - final PreparedPolygon jtsMultiPolygon; + public final OsmEntity parent; + public final PreparedPolygon jtsMultiPolygon; - OsmArea( + public OsmArea( OsmEntity parent, List outerRingWays, List innerRingWays, @@ -217,7 +217,7 @@ private boolean constructRingsRecursive( newRing.addAll(ring); newFirstEndpoint = firstEndpoint; } - if (newRing.get(newRing.size() - 1) == (newRing.get(0))) { + if (newRing.get(newRing.size() - 1) == newRing.get(0)) { // ring closure closedRings.add(newRing); // if we're out of endpoints, then we have succeeded diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmAreaGroup.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/OsmAreaGroup.java similarity index 96% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmAreaGroup.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/OsmAreaGroup.java index 4fb84de25d4..a1eb9393125 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmAreaGroup.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/OsmAreaGroup.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.model; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; @@ -18,7 +18,7 @@ import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.geom.LineString; import org.locationtech.jts.geom.Polygon; -import org.opentripplanner.graph_builder.module.osm.Ring.RingConstructionException; +import org.opentripplanner.graph_builder.module.osm.model.Ring.RingConstructionException; import org.opentripplanner.osm.model.OsmEntity; import org.opentripplanner.osm.model.OsmLevel; import org.opentripplanner.osm.model.OsmNode; @@ -30,19 +30,19 @@ /** * A group of possibly-contiguous areas sharing the same level */ -class OsmAreaGroup { +public class OsmAreaGroup { private static final Logger LOG = LoggerFactory.getLogger(OsmAreaGroup.class); /* * The list of underlying areas, used when generating edges out of the visibility graph */ - Collection areas; + public Collection areas; /** * The joined outermost rings of the areas (with inner rings for holes as necessary). */ - List outermostRings = new ArrayList<>(); + public List outermostRings = new ArrayList<>(); public final Geometry union; @@ -156,8 +156,7 @@ public static List groupAreas( boolean blocksTraversal = crossablePermissions.intersection( Objects.requireNonNull(barrier).getPermission() - ) != - crossablePermissions; + ) != crossablePermissions; boolean sharesEdgeWithBothAreas = !CollectionUtils.intersection( barriersForArea.get(area1).get(barrier), barriersForArea.get(area2).get(barrier) @@ -270,7 +269,8 @@ private Ring toRing(Polygon polygon, HashMap nodeMap) { */ public long cacheKey() { long hash = 1L; - long[] entityIds = this.areas.stream() + long[] entityIds = this.areas + .stream() .map(a -> a.parent) .mapToLong(OsmEntity::getId) .sorted() diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/OsmElevatorKey.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/OsmElevatorKey.java new file mode 100644 index 00000000000..1b02f2043b9 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/OsmElevatorKey.java @@ -0,0 +1,5 @@ +package org.opentripplanner.graph_builder.module.osm.model; + +import org.opentripplanner.street.model.vertex.OsmEntityType; + +public record OsmElevatorKey(long nodeId, OsmEntityType osmEntityType, long entityId) {} diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmNodePair.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/OsmNodePair.java similarity index 92% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmNodePair.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/OsmNodePair.java index a5886626b5d..98ae3e242ac 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmNodePair.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/OsmNodePair.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.model; import java.util.Objects; import org.opentripplanner.osm.model.OsmNode; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/Ring.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/Ring.java similarity index 97% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/Ring.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/Ring.java index b103905c5b1..69858cf725e 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/Ring.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/Ring.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.model; import gnu.trove.list.TLongList; import java.util.ArrayList; @@ -19,7 +19,7 @@ import org.opentripplanner.street.geometry.CoordinateArrayListSequence; import org.opentripplanner.street.geometry.GeometryUtils; -class Ring { +public class Ring { private final LinearRing shell; private final List holes = new ArrayList<>(); @@ -70,7 +70,7 @@ public void addHole(Ring hole) { /** * Checks whether the ith node in the ring is convex (has an angle of over 180 degrees). */ - boolean isNodeConvex(int i) { + public boolean isNodeConvex(int i) { int n = nodes.size() - 1; OsmNode cur = nodes.get(i); OsmNode prev = nodes.get((i + n - 1) % n); diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/StreetEdgePair.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/StreetEdgePair.java similarity index 93% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/StreetEdgePair.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/StreetEdgePair.java index 76ce28617fb..b357e8130b6 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/StreetEdgePair.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/StreetEdgePair.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.model; import java.util.ArrayList; import javax.annotation.Nullable; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionTag.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/TurnRestrictionTag.java similarity index 70% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionTag.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/TurnRestrictionTag.java index f71a55e6a34..af56a50385a 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionTag.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/model/TurnRestrictionTag.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.model; import java.util.ArrayList; import java.util.List; @@ -10,18 +10,23 @@ * A temporary holder for turn restrictions while we have only way/node ids but not yet edge * objects */ -class TurnRestrictionTag { +public class TurnRestrictionTag { - long via; + public long via; //Used only for issues so that it can be visualized in a map - long relationOsmID; - TurnRestrictionType type; - Direction direction; + public long relationOsmID; + public TurnRestrictionType type; + public Direction direction; public List possibleFrom = new ArrayList<>(); public List possibleTo = new ArrayList<>(); public TraverseModeSet modes; - TurnRestrictionTag(long via, TurnRestrictionType type, Direction direction, long relationOsmID) { + public TurnRestrictionTag( + long via, + TurnRestrictionType type, + Direction direction, + long relationOsmID + ) { this.via = via; this.type = type; this.direction = direction; @@ -33,7 +38,7 @@ public String toString() { return String.format("%s turn restriction via node %d", direction, via); } - enum Direction { + public enum Direction { LEFT, RIGHT, U, diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmProcessingParameters.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmProcessingParameters.java index c18982e7f4e..1f5a49f93a6 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmProcessingParameters.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmProcessingParameters.java @@ -1,11 +1,15 @@ package org.opentripplanner.graph_builder.module.osm.parameters; +import java.util.List; import java.util.Objects; import java.util.Set; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.EdgeNamer; +import org.opentripplanner.osm.model.CompoundRefTagGroup; /** * @param boardingAreaRefTags The ref tags to extract boarding locations from. + * @param elevatorRefTags Groups of OSM tags whose values are combined into elevator ids. + * The first group (in order) that resolves to a value is used. * @param edgeNamer Controls naming of edges. * @param maxAreaNodes Maximum number of nodes of an area to try to generate visibility * lines from. @@ -18,6 +22,7 @@ */ public record OsmProcessingParameters( Set boardingAreaRefTags, + List elevatorRefTags, EdgeNamer edgeNamer, int maxAreaNodes, boolean areaVisibility, @@ -29,6 +34,7 @@ public record OsmProcessingParameters( ) { public OsmProcessingParameters { boardingAreaRefTags = Set.copyOf(Objects.requireNonNull(boardingAreaRefTags)); + elevatorRefTags = List.copyOf(Objects.requireNonNull(elevatorRefTags)); Objects.requireNonNull(edgeNamer); } } diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmDatabase.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/storage/OsmDatabase.java similarity index 95% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmDatabase.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/storage/OsmDatabase.java index bfda6708f5a..fc571145c8a 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmDatabase.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/storage/OsmDatabase.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.storage; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.HashMultimap; @@ -22,7 +22,10 @@ import org.opentripplanner.graph_builder.issues.TurnRestrictionBad; import org.opentripplanner.graph_builder.issues.TurnRestrictionException; import org.opentripplanner.graph_builder.issues.TurnRestrictionUnknown; -import org.opentripplanner.graph_builder.module.osm.TurnRestrictionTag.Direction; +import org.opentripplanner.graph_builder.module.osm.model.OsmArea; +import org.opentripplanner.graph_builder.module.osm.model.Ring; +import org.opentripplanner.graph_builder.module.osm.model.TurnRestrictionTag; +import org.opentripplanner.graph_builder.module.osm.model.TurnRestrictionTag.Direction; import org.opentripplanner.osm.model.OsmEntity; import org.opentripplanner.osm.model.OsmLevel; import org.opentripplanner.osm.model.OsmLevelFactory; @@ -250,9 +253,11 @@ public void addNode(OsmNode node) { carParkingNodes.put(node.getId(), node); } if ( - !(waysNodeIds.contains(node.getId()) || + !( + waysNodeIds.contains(node.getId()) || areaNodeIds.contains(node.getId()) || - node.isBoardingLocation()) + node.isBoardingLocation() + ) ) { return; } @@ -285,12 +290,10 @@ public void addWay(OsmWay way) { singleWayAreas.add(way); areaWaysById.put(wayId, way); areaWayIds.add(wayId); - way - .getNodeRefs() - .forEach(node -> { - TroveUtils.addToMapSet(areasForNode, node, way); - return true; - }); + way.getNodeRefs().forEach(node -> { + TroveUtils.addToMapSet(areasForNode, node, way); + return true; + }); } return; } @@ -425,8 +428,10 @@ private void processMultipolygonRelations() { continue; } if ( - !(relation.isMultiPolygon() && - (relation.isRoutable() || relation.isParkAndRide() || relation.isBikeParking())) + !( + relation.isMultiPolygon() && + (relation.isRoutable() || relation.isParkAndRide() || relation.isBikeParking()) + ) ) { continue; } @@ -500,18 +505,16 @@ private void processRelations() { } private void setNetworkForAllMembers(OsmRelation relation, String key) { - relation - .getMembers() - .forEach(member -> { - var isOsmWay = member.hasTypeWay(); - var way = waysById.get(member.getRef()); - // if it is an OSM way (rather than a node) and it doesn't already contain the tag - // we add it - if (way != null && isOsmWay && !way.hasTag(key)) { - var updatedWay = way.copy().withTag(key, "yes").build(); - waysById.put(updatedWay.getId(), updatedWay); - } - }); + relation.getMembers().forEach(member -> { + var isOsmWay = member.hasTypeWay(); + var way = waysById.get(member.getRef()); + // if it is an OSM way (rather than a node) and it doesn't already contain the tag + // we add it + if (way != null && isOsmWay && !way.hasTag(key)) { + var updatedWay = way.copy().withTag(key, "yes").build(); + waysById.put(updatedWay.getId(), updatedWay); + } + }); } /** diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmNodeStore.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/storage/OsmNodeStore.java similarity index 96% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmNodeStore.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/storage/OsmNodeStore.java index 553c2945149..a4611a7a9fa 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmNodeStore.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/storage/OsmNodeStore.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.storage; import gnu.trove.map.TLongByteMap; import gnu.trove.map.TLongLongMap; @@ -160,14 +160,14 @@ private static long packCoordinate(double lat, double lon) { } int latFixed = (int) Math.round(lat * FIXED_POINT_FACTOR); int lonFixed = (int) Math.round(lon * FIXED_POINT_FACTOR); - return (((long) latFixed) << 32) | (lonFixed & 0xFFFFFFFFL); + return ((long) latFixed << 32) | (lonFixed & 0xFFFFFFFFL); } private static double unpackLat(long packedCoordinate) { - return ((int) (packedCoordinate >> 32)) / FIXED_POINT_FACTOR; + return (int) (packedCoordinate >> 32) / FIXED_POINT_FACTOR; } private static double unpackLon(long packedCoordinate) { - return ((int) packedCoordinate) / FIXED_POINT_FACTOR; + return (int) packedCoordinate / FIXED_POINT_FACTOR; } } diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/storage/VertexGenerator.java similarity index 93% rename from application/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/storage/VertexGenerator.java index 0cf9ae295b3..c756c8e7919 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/storage/VertexGenerator.java @@ -1,6 +1,6 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.storage; -import static org.opentripplanner.graph_builder.module.osm.LinearBarrierNodeType.SPLIT; +import static org.opentripplanner.graph_builder.module.osm.model.LinearBarrierNodeType.SPLIT; import com.google.common.collect.HashMultimap; import com.google.common.collect.Iterables; @@ -21,6 +21,10 @@ import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issues.BarrierIntersectingHighway; import org.opentripplanner.graph_builder.issues.DifferentLevelsSharingBarrier; +import org.opentripplanner.graph_builder.module.osm.model.LinearBarrierNodeType; +import org.opentripplanner.graph_builder.module.osm.model.OsmArea; +import org.opentripplanner.graph_builder.module.osm.model.OsmElevatorKey; +import org.opentripplanner.graph_builder.module.osm.model.Ring; import org.opentripplanner.osm.model.OsmEntity; import org.opentripplanner.osm.model.OsmLevel; import org.opentripplanner.osm.model.OsmNode; @@ -39,7 +43,7 @@ * Tracks the generation of vertices and returns an existing instance if a vertex is encountered * more than once. */ -class VertexGenerator { +public class VertexGenerator { private static final String NODE_LABEL_FORMAT = "osm:node:%d"; @@ -96,7 +100,7 @@ public VertexGenerator( * @return The graph vertex. This is not always an OSM vertex; it can also be a * {@link OsmBoardingLocationVertex} */ - IntersectionVertex getVertexForOsmNode( + public IntersectionVertex getVertexForOsmNode( OsmNode node, OsmEntity entity, LinearBarrierNodeType linearBarrierNodeType @@ -250,15 +254,15 @@ private List getLevelsForNode(OsmNode node, OsmEntity entity) { * Tracks OSM nodes which are decomposed into multiple graph vertices because they are * elevators. They can then be iterated over to build {@link ElevatorEdge} between them. */ - Map> elevatorNodes() { + public Map> elevatorNodes() { return elevatorNodes; } - HashMap elevatorNodeLevels() { + public HashMap elevatorNodeLevels() { return elevatorNodeLevels; } - void initIntersectionNodes() { + public void initIntersectionNodes() { Set possibleIntersectionNodes = new HashSet<>(); for (OsmWay way : osmdb.getWays()) { TLongList nodes = way.getNodeRefs(); @@ -283,7 +287,7 @@ void initIntersectionNodes() { } } - Collection getLinearBarriersAtNode(OsmNode node) { + public Collection getLinearBarriersAtNode(OsmNode node) { return nodesInBarrierWays.get(node); } @@ -292,7 +296,7 @@ Collection getLinearBarriersAtNode(OsmNode node) { * the vertex is in. The null-indexed vertex, if exists, is the vertex which hasn't been split * for a particular area and is applicable for all linear crossing of the barrier. */ - Map> splitVerticesOnBarriers() { + public Map> splitVerticesOnBarriers() { return splitVerticesOnBarriers; } @@ -300,7 +304,7 @@ public Multimap nodesInBarrierWays() { return nodesInBarrierWays; } - void initNodesInBarrierWays() { + public void initNodesInBarrierWays() { for (OsmWay way : osmdb.getWays()) { if (way.isBarrier()) { TLongList nodes = way.getNodeRefs(); @@ -325,7 +329,7 @@ void initNodesInBarrierWays() { * while it is still creating vertices. Use {@link #hasIntersectionVertex(long)} if you need to * know whether a vertex has actually been created. */ - boolean isIntersectionNode(long nodeId) { + public boolean isIntersectionNode(long nodeId) { return intersectionNodes.containsKey(nodeId); } @@ -339,7 +343,7 @@ boolean isIntersectionNode(long nodeId) { * de-duplicated away). Use this instead of {@link #isIntersectionNode(long)} when you need to * look up a vertex that must already exist. */ - boolean hasIntersectionVertex(long nodeId) { + public boolean hasIntersectionVertex(long nodeId) { return intersectionNodes.get(nodeId) != null; } @@ -347,7 +351,7 @@ boolean hasIntersectionVertex(long nodeId) { * Return the graph vertex already created for the given intersection node id. Throws an exception * if the node is not an intersection node, or a vertex hasn't been created for it yet. */ - IntersectionVertex getIntersectionVertex(long nodeId) { + public IntersectionVertex getIntersectionVertex(long nodeId) { return Objects.requireNonNull( intersectionNodes.get(nodeId), "Intersection vertex %s not found.".formatted(nodeId) diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/stopconnectivity/StopConnectivityModule.java b/application/src/main/java/org/opentripplanner/graph_builder/module/stopconnectivity/StopConnectivityModule.java index 20b09fba181..fee6500aae2 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/stopconnectivity/StopConnectivityModule.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/stopconnectivity/StopConnectivityModule.java @@ -36,6 +36,9 @@ public StopConnectivityModule(Graph graph, DataImportIssueStore issueStore) { @Override public void buildGraph() { + if (!graph.hasStreets) { + return; + } var progress = ProgressTracker.track( "Stop connectivity analysis", 5000, diff --git a/application/src/main/java/org/opentripplanner/gtfs/mapping/TransferMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/TransferMapper.java index 3a22556959f..a5ab829be17 100644 --- a/application/src/main/java/org/opentripplanner/gtfs/mapping/TransferMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/TransferMapper.java @@ -263,9 +263,10 @@ private TransferPoint mapTransferPoint( private int boardStopPosition(Trip trip, RegularStop stop, Station station) { List stopTimes = stopTimesByTrip.get(trip); - Predicate stopMatches = station != null - ? s -> ((s instanceof RegularStop regStop) && regStop.getParentStation() == station) - : s -> s == stop; + Predicate stopMatches = + station != null + ? s -> s instanceof RegularStop regStop && regStop.getParentStation() == station + : s -> s == stop; for (int i = 0; i < stopTimes.size() - 1; i++) { StopTime stopTime = stopTimes.get(i); @@ -283,9 +284,10 @@ private int boardStopPosition(Trip trip, RegularStop stop, Station station) { private int alightStopPosition(Trip trip, RegularStop stop, Station station) { List stopTimes = stopTimesByTrip.get(trip); - Predicate stopMatches = station != null - ? s -> ((s instanceof RegularStop regStop) && regStop.getParentStation() == station) - : s -> s == stop; + Predicate stopMatches = + station != null + ? s -> s instanceof RegularStop regStop && regStop.getParentStation() == station + : s -> s == stop; for (int i = stopTimes.size() - 1; i > 0; i--) { StopTime stopTime = stopTimes.get(i); diff --git a/application/src/main/java/org/opentripplanner/gtfs/mapping/TranslationHelper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/TranslationHelper.java index 5a926e70e3b..4c32ec46809 100644 --- a/application/src/main/java/org/opentripplanner/gtfs/mapping/TranslationHelper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/TranslationHelper.java @@ -45,7 +45,10 @@ void importTranslations(Collection allTranslations, Collection={""=[Translation@1, ..., Translation@Z]}} translationMap.put( tableName, - i.getValue().stream().collect(Collectors.groupingBy(t -> "")) + i + .getValue() + .stream() + .collect(Collectors.groupingBy(t -> "")) ); } else { // will create with following structure: diff --git a/application/src/main/java/org/opentripplanner/gtfs/mapping/TripMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/TripMapper.java index 5d7eaa8afad..4ae0ad44eec 100644 --- a/application/src/main/java/org/opentripplanner/gtfs/mapping/TripMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/TripMapper.java @@ -84,12 +84,12 @@ private Optional mapSafeTimePenalty(org.onebusaway.gtfs.model.Trip if (rhs.getSafeDurationFactor() == null && rhs.getSafeDurationOffset() == null) { return Optional.empty(); } else { - var offset = rhs.getSafeDurationOffset() == null - ? Duration.ZERO - : Duration.ofSeconds(rhs.getSafeDurationOffset().longValue()); - var factor = rhs.getSafeDurationFactor() == null - ? 1d - : rhs.getSafeDurationFactor().doubleValue(); + var offset = + rhs.getSafeDurationOffset() == null + ? Duration.ZERO + : Duration.ofSeconds(rhs.getSafeDurationOffset().longValue()); + var factor = + rhs.getSafeDurationFactor() == null ? 1d : rhs.getSafeDurationFactor().doubleValue(); return Optional.of(TimePenalty.of(offset, factor)); } } diff --git a/application/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java b/application/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java index 0d7f9b1b254..95d4c156945 100644 --- a/application/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java +++ b/application/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java @@ -79,11 +79,12 @@ private Double findElevationForVertex(Vertex v) { .getIncomingStreetEdges() .stream() .filter(StreetEdge::hasElevationExtension) - .map(streetEdge -> - streetEdge - .getElevationProfile() - .getCoordinate(streetEdge.getElevationProfile().size() - 1) - .y + .map( + streetEdge -> + streetEdge + .getElevationProfile() + .getCoordinate(streetEdge.getElevationProfile().size() - 1) + .y ), v .getOutgoingStreetEdges() diff --git a/application/src/main/java/org/opentripplanner/kryo/UnmodifiableCollectionsSerializer.java b/application/src/main/java/org/opentripplanner/kryo/UnmodifiableCollectionsSerializer.java index d5617270ea7..52855b4b1f8 100644 --- a/application/src/main/java/org/opentripplanner/kryo/UnmodifiableCollectionsSerializer.java +++ b/application/src/main/java/org/opentripplanner/kryo/UnmodifiableCollectionsSerializer.java @@ -72,7 +72,7 @@ public void write(Kryo kryo, Output output, Object object) { ); // the ordinal could be replaced by s.th. else (e.g. a explicitely managed "id") output.writeInt(unmodifiableCollection.ordinal(), true); - kryo.writeClassAndObject(output, getValues(object)); + kryo.writeClassAndObject(output, unmodifiableCollection.toKryoSerializedObject(object)); } catch (RuntimeException e) { // Don't eat and wrap RuntimeExceptions because the ObjectBuffer.write... // handles SerializationException specifically (resizing the buffer)... @@ -86,8 +86,8 @@ public void write(Kryo kryo, Output output, Object object) { public Object read(Kryo kryo, Input input, Class clazz) { int ordinal = input.readInt(true); UnmodifiableCollection unmodifiableCollection = UnmodifiableCollection.values()[ordinal]; - Object sourceCollection = kryo.readClassAndObject(input); - return unmodifiableCollection.create(sourceCollection); + Object intermediate = kryo.readClassAndObject(input); + return unmodifiableCollection.fromKryoSerializedObject(intermediate); } @Override @@ -96,8 +96,8 @@ public Object copy(Kryo kryo, Object original) { UnmodifiableCollection unmodifiableCollection = UnmodifiableCollection.valueOfType( original.getClass() ); - Object sourceCollectionCopy = kryo.copy(getValues(original)); - return unmodifiableCollection.create(sourceCollectionCopy); + Object intermediateCopy = kryo.copy(unmodifiableCollection.toKryoSerializedObject(original)); + return unmodifiableCollection.fromKryoSerializedObject(intermediateCopy); } catch (RuntimeException e) { // Don't eat and wrap RuntimeExceptions throw e; @@ -106,51 +106,102 @@ public Object copy(Kryo kryo, Object original) { } } - private Collection getValues(Object coll) { - return new ArrayList<>((Collection) coll); - } - + /** + * Each variant converts to/from a plain, Kryo-friendly intermediate representation on write/copy + * ({@link #toKryoSerializedObject}), and reconstructs the concrete collection/map type it needs before + * wrapping it back up as unmodifiable on read/copy ({@link #fromKryoSerializedObject}). This is deliberately not + * symmetric (e.g. {@code Map} isn't a {@code Collection}, and the intermediate {@code ArrayList} + * read back for a {@code Set} isn't itself a {@code Set}), so each side needs its own conversion + * rather than a single shared cast. + */ private enum UnmodifiableCollection { COLLECTION(Collections.unmodifiableCollection(Arrays.asList("")).getClass()) { @Override - public Object create(Object sourceCollection) { - return Collections.unmodifiableCollection((Collection) sourceCollection); + Object toKryoSerializedObject(Object source) { + return new ArrayList<>((Collection) source); + } + + @Override + public Object fromKryoSerializedObject(Object serializedObject) { + return Collections.unmodifiableCollection((Collection) serializedObject); } }, RANDOM_ACCESS_LIST(Collections.unmodifiableList(new ArrayList()).getClass()) { @Override - public Object create(Object sourceCollection) { - return Collections.unmodifiableList((List) sourceCollection); + Object toKryoSerializedObject(Object source) { + return new ArrayList<>((Collection) source); + } + + @Override + public Object fromKryoSerializedObject(Object serializedObject) { + return Collections.unmodifiableList(new ArrayList<>((Collection) serializedObject)); } }, LIST(Collections.unmodifiableList(new LinkedList()).getClass()) { @Override - public Object create(Object sourceCollection) { - return Collections.unmodifiableList((List) sourceCollection); + Object toKryoSerializedObject(Object source) { + return new ArrayList<>((Collection) source); + } + + @Override + public Object fromKryoSerializedObject(Object serializedObject) { + return Collections.unmodifiableList(new LinkedList<>((Collection) serializedObject)); } }, SET(Collections.unmodifiableSet(new HashSet()).getClass()) { @Override - public Object create(Object sourceCollection) { - return Collections.unmodifiableSet((Set) sourceCollection); + Object toKryoSerializedObject(Object source) { + return new ArrayList<>((Collection) source); + } + + @Override + public Object fromKryoSerializedObject(Object serializedObject) { + return Collections.unmodifiableSet(new HashSet<>((Collection) serializedObject)); } }, SORTED_SET(Collections.unmodifiableSortedSet(new TreeSet()).getClass()) { @Override - public Object create(Object sourceCollection) { - return Collections.unmodifiableSortedSet((SortedSet) sourceCollection); + Object toKryoSerializedObject(Object source) { + if (((SortedSet) source).comparator() != null) { + throw new UnsupportedOperationException( + "Serializing a SortedSet with a custom comparator is not supported, " + + "the comparator would be lost on deserialization." + ); + } + return new ArrayList<>((Collection) source); + } + + @Override + public Object fromKryoSerializedObject(Object serializedObject) { + return Collections.unmodifiableSortedSet(new TreeSet<>((Collection) serializedObject)); } }, MAP(Collections.unmodifiableMap(new HashMap()).getClass()) { @Override - public Object create(Object sourceCollection) { - return Collections.unmodifiableMap((Map) sourceCollection); + Object toKryoSerializedObject(Object source) { + return new HashMap<>((Map) source); + } + + @Override + public Object fromKryoSerializedObject(Object serializedObject) { + return Collections.unmodifiableMap(new HashMap<>((Map) serializedObject)); } }, SORTED_MAP(Collections.unmodifiableSortedMap(new TreeMap()).getClass()) { @Override - public Object create(Object sourceCollection) { - return Collections.unmodifiableSortedMap((SortedMap) sourceCollection); + Object toKryoSerializedObject(Object source) { + if (((SortedMap) source).comparator() != null) { + throw new UnsupportedOperationException( + "Serializing a SortedMap with a custom comparator is not supported, " + + "the comparator would be lost on deserialization." + ); + } + return new HashMap<>((Map) source); + } + + @Override + public Object fromKryoSerializedObject(Object serializedObject) { + return Collections.unmodifiableSortedMap(new TreeMap<>((Map) serializedObject)); } }; @@ -160,7 +211,17 @@ public Object create(Object sourceCollection) { this.type = type; } - public abstract Object create(Object sourceCollection); + /** + * Converts an unmodifiable collection/map wrapper into a mutable, Kryo-friendly intermediate + * representation before serialization or copy. + */ + abstract Object toKryoSerializedObject(Object source); + + /** + * Reconstructs the expected collection/map implementation from the intermediate representation, + * then wraps it back into the matching unmodifiable type. + */ + public abstract Object fromKryoSerializedObject(Object serializedObject); static UnmodifiableCollection valueOfType(Class type) { for (UnmodifiableCollection item : values()) { diff --git a/application/src/main/java/org/opentripplanner/model/plan/Leg.java b/application/src/main/java/org/opentripplanner/model/plan/Leg.java index 0dbcdcf1ed6..1b5f782f268 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/Leg.java +++ b/application/src/main/java/org/opentripplanner/model/plan/Leg.java @@ -20,7 +20,6 @@ import org.opentripplanner.model.plan.walkstep.WalkStep; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.street.model.elevation.ElevationProfile; -import org.opentripplanner.street.model.note.StreetNote; import org.opentripplanner.transfer.constrained.model.ConstrainedTransfer; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Agency; @@ -365,10 +364,6 @@ default List listWalkSteps() { return List.of(); } - default Set listStreetNotes() { - return Set.of(); - } - Set listTransitAlerts(); @Nullable diff --git a/application/src/main/java/org/opentripplanner/model/plan/leg/FrequencyTransitLeg.java b/application/src/main/java/org/opentripplanner/model/plan/leg/FrequencyTransitLeg.java index 7e01547dd7b..5a59dc7cbea 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/leg/FrequencyTransitLeg.java +++ b/application/src/main/java/org/opentripplanner/model/plan/leg/FrequencyTransitLeg.java @@ -44,7 +44,7 @@ public boolean isPartiallySameTransitLeg(Leg other) { if (other instanceof FrequencyTransitLeg frequencyTransitLeg) { var start = tripTimes().getDepartureTime(0); var otherStart = frequencyTransitLeg.tripTimes().getDepartureTime(0); - return same && (start == otherStart); + return same && start == otherStart; } else { return same; } diff --git a/application/src/main/java/org/opentripplanner/model/plan/leg/FrequencyTransitLegBuilder.java b/application/src/main/java/org/opentripplanner/model/plan/leg/FrequencyTransitLegBuilder.java index 4088618c67c..7f77f113795 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/leg/FrequencyTransitLegBuilder.java +++ b/application/src/main/java/org/opentripplanner/model/plan/leg/FrequencyTransitLegBuilder.java @@ -1,7 +1,8 @@ package org.opentripplanner.model.plan.leg; public class FrequencyTransitLegBuilder - extends ScheduledTransitLegBuilder { + extends ScheduledTransitLegBuilder +{ private int frequencyHeadwayInSeconds; diff --git a/application/src/main/java/org/opentripplanner/model/plan/leg/ScheduledTransitLeg.java b/application/src/main/java/org/opentripplanner/model/plan/leg/ScheduledTransitLeg.java index a88faee7bd9..6c390c143ff 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/leg/ScheduledTransitLeg.java +++ b/application/src/main/java/org/opentripplanner/model/plan/leg/ScheduledTransitLeg.java @@ -230,20 +230,16 @@ public ZonedDateTime endTime() { @Override public int departureDelay() { - return ( - tripTimes.isCanceledStop(boardStopPosInPattern) || - tripTimes.isNoDataStop(boardStopPosInPattern) - ) + return tripTimes.isCanceledStop(boardStopPosInPattern) || + tripTimes.isNoDataStop(boardStopPosInPattern) ? 0 : tripTimes.getDepartureDelay(boardStopPosInPattern); } @Override public int arrivalDelay() { - return ( - tripTimes.isCanceledStop(alightStopPosInPattern) || - tripTimes.isNoDataStop(alightStopPosInPattern) - ) + return tripTimes.isCanceledStop(alightStopPosInPattern) || + tripTimes.isNoDataStop(alightStopPosInPattern) ? 0 : tripTimes.getArrivalDelay(alightStopPosInPattern); } diff --git a/application/src/main/java/org/opentripplanner/model/plan/leg/StreetLeg.java b/application/src/main/java/org/opentripplanner/model/plan/leg/StreetLeg.java index b8f457b9830..3a742f040b6 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/leg/StreetLeg.java +++ b/application/src/main/java/org/opentripplanner/model/plan/leg/StreetLeg.java @@ -14,7 +14,6 @@ import org.opentripplanner.model.plan.walkstep.WalkStep; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.street.model.elevation.ElevationProfile; -import org.opentripplanner.street.model.note.StreetNote; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.utils.lang.DoubleUtils; import org.opentripplanner.utils.time.TimeUtils; @@ -35,7 +34,6 @@ public class StreetLeg implements Leg { private final int generalizedCost; private final LineString legGeometry; private final List walkSteps; - private final Set streetNotes; private final ElevationProfile elevationProfile; private final Boolean walkingBike; @@ -55,7 +53,6 @@ protected StreetLeg(StreetLegBuilder builder) { this.elevationProfile = builder.getElevationProfile(); this.legGeometry = builder.getGeometry(); this.walkSteps = Objects.requireNonNull(builder.getWalkSteps()); - this.streetNotes = Set.copyOf(builder.getStreetNotes()); this.walkingBike = builder.getWalkingBike(); this.rentedVehicle = builder.getRentedVehicle(); this.vehicleRentalNetwork = builder.getVehicleRentalNetwork(); @@ -133,11 +130,6 @@ public List listWalkSteps() { return walkSteps; } - @Override - public Set listStreetNotes() { - return streetNotes; - } - @Override public Set listTransitAlerts() { return Set.of(); @@ -229,7 +221,6 @@ public String toString() { .addEnum("mode", mode) .addNum("distance", distanceMeters, "m") .addNum("cost", generalizedCost) - .addCol("streetNotes", streetNotes) .addBool("walkingBike", walkingBike) .addBool("rentedVehicle", rentedVehicle) .addStr("bikeRentalNetwork", vehicleRentalNetwork) diff --git a/application/src/main/java/org/opentripplanner/model/plan/leg/StreetLegBuilder.java b/application/src/main/java/org/opentripplanner/model/plan/leg/StreetLegBuilder.java index d0de3694e39..c6d013d17ec 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/leg/StreetLegBuilder.java +++ b/application/src/main/java/org/opentripplanner/model/plan/leg/StreetLegBuilder.java @@ -1,16 +1,13 @@ package org.opentripplanner.model.plan.leg; import java.time.ZonedDateTime; -import java.util.HashSet; import java.util.List; import java.util.Objects; -import java.util.Set; import org.locationtech.jts.geom.LineString; import org.opentripplanner.model.plan.Emission; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.walkstep.WalkStep; import org.opentripplanner.street.model.elevation.ElevationProfile; -import org.opentripplanner.street.model.note.StreetNote; import org.opentripplanner.street.search.TraverseMode; public class StreetLegBuilder { @@ -28,7 +25,6 @@ public class StreetLegBuilder { private Boolean walkingBike; private Boolean rentedVehicle; private String vehicleRentalNetwork; - private Set streetNotes = new HashSet<>(); private Float accessibilityScore; private Emission emissionPerPerson; @@ -48,7 +44,6 @@ protected StreetLegBuilder(StreetLeg leg) { this.walkingBike = leg.walkingBike(); this.rentedVehicle = leg.rentedVehicle(); this.vehicleRentalNetwork = leg.vehicleRentalNetwork(); - this.streetNotes = Set.copyOf(leg.listStreetNotes()); this.accessibilityScore = leg.accessibilityScore(); this.emissionPerPerson = leg.emissionPerPerson(); } @@ -113,10 +108,6 @@ public Float getAccessibilityScore() { return accessibilityScore; } - public Set getStreetNotes() { - return streetNotes; - } - public Emission emissionPerPerson() { return emissionPerPerson; } @@ -186,11 +177,6 @@ public StreetLegBuilder withVehicleRentalNetwork(String vehicleRentalNetwork) { return this; } - public StreetLegBuilder withStreetNotes(Set notes) { - streetNotes = notes; - return this; - } - public StreetLegBuilder withAccessibilityScore(Float accessibilityScore) { this.accessibilityScore = accessibilityScore; return this; diff --git a/application/src/main/java/org/opentripplanner/model/plan/leg/UnknownPathLeg.java b/application/src/main/java/org/opentripplanner/model/plan/leg/UnknownPathLeg.java index c53358b9647..cacab6cc28a 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/leg/UnknownPathLeg.java +++ b/application/src/main/java/org/opentripplanner/model/plan/leg/UnknownPathLeg.java @@ -128,7 +128,7 @@ public int getNumberOfTransfers() { } public String description() { - return ("Unknown transit " + nTransfers + "tx " + DurationUtils.durationToStr(duration())); + return "Unknown transit " + nTransfers + "tx " + DurationUtils.durationToStr(duration()); } @Override diff --git a/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactory.java b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactory.java index 86eae33a218..bd0ee49d51f 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactory.java +++ b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactory.java @@ -53,9 +53,8 @@ public PageCursorFactory withOriginalSearch( Instant lat, Duration searchWindow ) { - this.currentPageType = pageType == null - ? resolvePageTypeForTheFirstSearch(sortOrder) - : pageType; + this.currentPageType = + pageType == null ? resolvePageTypeForTheFirstSearch(sortOrder) : pageType; this.firstSearchLatestItineraryDeparture = resolveFirstSearchLatestItineraryDeparture( pageType, firstItineraryResultDeparture, diff --git a/application/src/main/java/org/opentripplanner/model/plan/walkstep/WalkStep.java b/application/src/main/java/org/opentripplanner/model/plan/walkstep/WalkStep.java index eec612b4bdc..5696a38dfeb 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/walkstep/WalkStep.java +++ b/application/src/main/java/org/opentripplanner/model/plan/walkstep/WalkStep.java @@ -3,14 +3,12 @@ import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.Set; import javax.annotation.Nullable; import org.opentripplanner.core.model.i18n.I18NString; import org.opentripplanner.model.plan.walkstep.verticaltransportation.VerticalTransportationUse; import org.opentripplanner.street.geometry.WgsCoordinate; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.elevation.ElevationProfile; -import org.opentripplanner.street.model.note.StreetNote; import org.opentripplanner.transit.model.site.Entrance; import org.opentripplanner.utils.lang.DoubleUtils; import org.opentripplanner.utils.tostring.ToStringBuilder; @@ -40,8 +38,6 @@ public final class WalkStep { private final I18NString directionText; private final AbsoluteDirection absoluteDirection; - private final Set streetNotes; - private final boolean area; private final boolean nameIsDerived; private final double angle; @@ -65,7 +61,6 @@ public final class WalkStep { RelativeDirection relativeDirection, AbsoluteDirection absoluteDirection, I18NString directionText, - Set streetNotes, String highwayExit, @Nullable Entrance entrance, @Nullable VerticalTransportationUse verticalTransportationUse, @@ -82,7 +77,6 @@ public final class WalkStep { this.relativeDirection = Objects.requireNonNull(relativeDirection); this.absoluteDirection = absoluteDirection; this.directionText = directionText; - this.streetNotes = Set.copyOf(Objects.requireNonNull(streetNotes)); this.startLocation = Objects.requireNonNull(startLocation); this.nameIsDerived = nameIsDerived; this.angle = DoubleUtils.roundTo2Decimals(angle); @@ -100,10 +94,6 @@ public ElevationProfile getElevationProfile() { return elevationProfile; } - public Set getStreetNotes() { - return streetNotes; - } - /** * The distance in meters that this step takes. */ diff --git a/application/src/main/java/org/opentripplanner/model/plan/walkstep/WalkStepBuilder.java b/application/src/main/java/org/opentripplanner/model/plan/walkstep/WalkStepBuilder.java index 9633ebb2c5b..82a23881a32 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/walkstep/WalkStepBuilder.java +++ b/application/src/main/java/org/opentripplanner/model/plan/walkstep/WalkStepBuilder.java @@ -1,23 +1,19 @@ package org.opentripplanner.model.plan.walkstep; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; import javax.annotation.Nullable; import org.opentripplanner.core.model.i18n.I18NString; import org.opentripplanner.model.plan.walkstep.verticaltransportation.VerticalTransportationUse; import org.opentripplanner.street.geometry.WgsCoordinate; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.elevation.ElevationProfile; -import org.opentripplanner.street.model.note.StreetNote; import org.opentripplanner.transit.model.site.Entrance; import org.opentripplanner.utils.lang.DoubleUtils; import org.opentripplanner.utils.lang.IntUtils; public class WalkStepBuilder { - private final Set streetNotes = new HashSet<>(); private I18NString directionText; private WgsCoordinate startLocation; private boolean nameIsDerived = false; @@ -169,11 +165,6 @@ public VerticalTransportationUse verticalTransportationUse() { return verticalTransportationUse; } - public WalkStepBuilder addStreetNotes(Set notes) { - this.streetNotes.addAll(notes); - return this; - } - public I18NString directionText() { return directionText; } @@ -199,7 +190,6 @@ public WalkStep build() { relativeDirection, absoluteDirection, directionText, - streetNotes, exit, entrance, verticalTransportationUse, diff --git a/application/src/main/java/org/opentripplanner/model/plan/walkstep/verticaltransportation/VerticalTransportationUse.java b/application/src/main/java/org/opentripplanner/model/plan/walkstep/verticaltransportation/VerticalTransportationUse.java index 2b1e1973553..5b608225f2f 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/walkstep/verticaltransportation/VerticalTransportationUse.java +++ b/application/src/main/java/org/opentripplanner/model/plan/walkstep/verticaltransportation/VerticalTransportationUse.java @@ -9,7 +9,8 @@ * {@link org.opentripplanner.model.plan.walkstep.WalkStep}. */ public abstract sealed class VerticalTransportationUse - permits ElevatorUse, EscalatorUse, StairsUse { + permits ElevatorUse, EscalatorUse, StairsUse +{ private final Level from; private final Level to; diff --git a/application/src/main/java/org/opentripplanner/model/plan/walkstep/verticaltransportation/VerticalTransportationUseFactory.java b/application/src/main/java/org/opentripplanner/model/plan/walkstep/verticaltransportation/VerticalTransportationUseFactory.java index 278d868f534..62b8d3ee4e3 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/walkstep/verticaltransportation/VerticalTransportationUseFactory.java +++ b/application/src/main/java/org/opentripplanner/model/plan/walkstep/verticaltransportation/VerticalTransportationUseFactory.java @@ -113,10 +113,8 @@ private VerticalDirection getInclinedEdgeVerticalDirection( Edge edge, InclinedEdgeLevelInfo inclinedEdgeLevelInfo ) { - return ( - edge.getFromVertex() instanceof OsmVertex fromVertex && - fromVertex.nodeId() == inclinedEdgeLevelInfo.lowerVertexInfo().osmNodeId() - ) + return edge.getFromVertex() instanceof OsmVertex fromVertex && + fromVertex.nodeId() == inclinedEdgeLevelInfo.lowerVertexInfo().osmNodeId() ? VerticalDirection.UP : VerticalDirection.DOWN; } diff --git a/application/src/main/java/org/opentripplanner/netex/index/NetexEntityIndex.java b/application/src/main/java/org/opentripplanner/netex/index/NetexEntityIndex.java index 76e82327040..b3dae8357fd 100644 --- a/application/src/main/java/org/opentripplanner/netex/index/NetexEntityIndex.java +++ b/application/src/main/java/org/opentripplanner/netex/index/NetexEntityIndex.java @@ -224,9 +224,10 @@ public NetexEntityIndexReadOnlyView readOnlyView() { public Network lookupNetworkForLine(String groupOfLineOrNetworkId) { GroupOfLines groupOfLines = groupOfLinesById.lookup(groupOfLineOrNetworkId); - String networkId = groupOfLines == null - ? groupOfLineOrNetworkId - : networkIdByGroupOfLineId.lookup(groupOfLines.getId()); + String networkId = + groupOfLines == null + ? groupOfLineOrNetworkId + : networkIdByGroupOfLineId.lookup(groupOfLines.getId()); return networkById.lookup(networkId); } @@ -314,9 +315,7 @@ public ReadOnlyHierarchicalMapById getOperatingDayById() { } @Override - public ReadOnlyHierarchicalMapById< - OperatingPeriod_VersionStructure - > getOperatingPeriodById() { + public ReadOnlyHierarchicalMapById getOperatingPeriodById() { return operatingPeriodById; } @@ -351,9 +350,7 @@ public ReadOnlyHierarchicalMapById getServiceJourneyById() { } @Override - public ReadOnlyHierarchicalMapById< - ServiceJourneyInterchange - > getServiceJourneyInterchangeById() { + public ReadOnlyHierarchicalMapById getServiceJourneyInterchangeById() { return serviceJourneyInterchangeById; } diff --git a/application/src/main/java/org/opentripplanner/netex/index/hierarchy/AbstractHierarchicalMap.java b/application/src/main/java/org/opentripplanner/netex/index/hierarchy/AbstractHierarchicalMap.java index 98403332058..ccd27f4be06 100644 --- a/application/src/main/java/org/opentripplanner/netex/index/hierarchy/AbstractHierarchicalMap.java +++ b/application/src/main/java/org/opentripplanner/netex/index/hierarchy/AbstractHierarchicalMap.java @@ -37,7 +37,7 @@ public abstract class AbstractHierarchicalMap implements ReadOnlyHierarchi */ @Override public V lookup(K key) { - return (localContainsKey(key) || isRoot()) ? localGet(key) : parent.lookup(key); + return localContainsKey(key) || isRoot() ? localGet(key) : parent.lookup(key); } /** diff --git a/application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMapById.java b/application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMapById.java index 7e348725164..0929730fa09 100644 --- a/application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMapById.java +++ b/application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMapById.java @@ -13,7 +13,8 @@ */ public class HierarchicalMapById extends HierarchicalMap - implements ReadOnlyHierarchicalMapById { + implements ReadOnlyHierarchicalMapById +{ /** Create a root for the hierarchy */ public HierarchicalMapById() {} diff --git a/application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalVersionMapById.java b/application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalVersionMapById.java index ac0f0d1004b..531eb0e96f4 100644 --- a/application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalVersionMapById.java +++ b/application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalVersionMapById.java @@ -22,7 +22,8 @@ */ public class HierarchicalVersionMapById extends HierarchicalMultimap - implements ReadOnlyHierarchicalVersionMapById { + implements ReadOnlyHierarchicalVersionMapById +{ /** Create a root for the hierarchy */ public HierarchicalVersionMapById() {} diff --git a/application/src/main/java/org/opentripplanner/netex/loader/parser/NetexParser.java b/application/src/main/java/org/opentripplanner/netex/loader/parser/NetexParser.java index 6fa1ebb4192..801a318d6cb 100644 --- a/application/src/main/java/org/opentripplanner/netex/loader/parser/NetexParser.java +++ b/application/src/main/java/org/opentripplanner/netex/loader/parser/NetexParser.java @@ -1,5 +1,6 @@ package org.opentripplanner.netex.loader.parser; +import jakarta.xml.bind.JAXBElement; import java.util.Collection; import org.opentripplanner.netex.index.NetexEntityIndex; import org.rutebanken.netex.model.VersionFrame_VersionStructure; @@ -52,11 +53,10 @@ static void warnOnMissingMapping(Logger log, Object rel) { if (rel instanceof Collection) { throw new IllegalArgumentException("Do not pass in collections to this method."); } - log.warn("Netex import - Element mapping is missing for {}.", rel.getClass().getName()); + log.warn("Netex import - Element mapping is missing for {}.", resolveXmlTypeName(rel)); } /* static methods for logging unhandled elements - this ensure consistent logging. */ - /** * Unsupported elements are not relevant for Transit Routing, if you really think they should be * used in transit routing feel free to report an issue OTP GitHub. @@ -68,7 +68,7 @@ static void informOnElementIntentionallySkipped(Logger log, Object rel) { if (rel instanceof Collection) { throw new IllegalArgumentException("Do not pass in collections to this method."); } - log.info("Netex import - Element skipped: {}", rel.getClass().getName()); + log.info("Netex import - Element skipped: {}", resolveXmlTypeName(rel)); } /** Perform parsing and keep the parsed objects internally. */ @@ -76,4 +76,18 @@ static void informOnElementIntentionallySkipped(Logger log, Object rel) { /** Add the result - the parsed objects - to the index. */ abstract void setResultOnIndex(NetexEntityIndex netexIndex); + + /** + * Resolve the type name of the element for printing in the log. + *

+ * Generally this is just the Java class name, but JAXB sometimes wraps them in a JAXBElement which + * would log as "JAXBElement". In such a case, the class name of the wrapped object is returned. + */ + private static String resolveXmlTypeName(Object rel) { + if (rel instanceof JAXBElement jaxb) { + return jaxb.getDeclaredType().getName(); + } else { + return rel.getClass().getName(); + } + } } diff --git a/application/src/main/java/org/opentripplanner/netex/mapping/NoticeAssignmentMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/NoticeAssignmentMapper.java index 1c8cda0e70f..23991be0012 100644 --- a/application/src/main/java/org/opentripplanner/netex/mapping/NoticeAssignmentMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/NoticeAssignmentMapper.java @@ -118,9 +118,10 @@ Multimap map(NoticeAssignment noticeAssignment) { @Nullable private Notice getOrMapNotice(NoticeAssignment assignment) { - org.rutebanken.netex.model.Notice notice = assignment.getNotice() != null - ? assignment.getNotice() - : noticesById.lookup(assignment.getNoticeRef().getRef()); + org.rutebanken.netex.model.Notice notice = + assignment.getNotice() != null + ? assignment.getNotice() + : noticesById.lookup(assignment.getNoticeRef().getRef()); return notice == null ? null : noticeMapper.map(notice); } diff --git a/application/src/main/java/org/opentripplanner/netex/mapping/OpenGisMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/OpenGisMapper.java index de148de795e..4fdf8a96b56 100644 --- a/application/src/main/java/org/opentripplanner/netex/mapping/OpenGisMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/OpenGisMapper.java @@ -40,9 +40,9 @@ static Geometry mapGeometry(PolygonType polygonType) { private static CoordinateSequence mapCoordinateSequence( AbstractRingPropertyType abstractRingPropertyType ) { - List posList = ((LinearRingType) abstractRingPropertyType - .getAbstractRing() - .getValue()).getPosList().getValue(); + List posList = ((LinearRingType) abstractRingPropertyType.getAbstractRing().getValue()) + .getPosList() + .getValue(); // Convert a single list of alternating lat/lon values into coordinates ArrayList coordinates = new ArrayList<>(); diff --git a/application/src/main/java/org/opentripplanner/netex/mapping/StationMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/StationMapper.java index 99642bb5f58..e983030883f 100644 --- a/application/src/main/java/org/opentripplanner/netex/mapping/StationMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/StationMapper.java @@ -115,9 +115,8 @@ private I18NString resolveName(StopPlace stopPlace) { translations.put(null, stopPlace.getName().getValue()); for (var translation : stopPlace.getAlternativeNames().getAlternativeName()) { if (translation.getNameType() == NameTypeEnumeration.TRANSLATION) { - String lang = translation.getLang() != null - ? translation.getLang() - : translation.getName().getLang(); + String lang = + translation.getLang() != null ? translation.getLang() : translation.getName().getLang(); translations.put(lang, translation.getName().getValue()); } } diff --git a/application/src/main/java/org/opentripplanner/netex/mapping/TariffZoneMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/TariffZoneMapper.java index 9ca1e34f802..fee31bfdb19 100644 --- a/application/src/main/java/org/opentripplanner/netex/mapping/TariffZoneMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/TariffZoneMapper.java @@ -44,7 +44,7 @@ Collection listAllCurrentFareZones() { */ FareZone findAndMapTariffZone(TariffZoneRef ref) { var tariffZone = tariffZonesById.lookup(ref, startOfPeriod); - return (tariffZone == null) ? null : mapTariffZone(tariffZone); + return tariffZone == null ? null : mapTariffZone(tariffZone); } /** diff --git a/application/src/main/java/org/opentripplanner/netex/mapping/TransferMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/TransferMapper.java index 98f47af5e0e..ceff7db08a9 100644 --- a/application/src/main/java/org/opentripplanner/netex/mapping/TransferMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/TransferMapper.java @@ -95,7 +95,7 @@ private TripTransferPoint mapPoint( var sjId = sjRef.getRef(); var trip = findTrip(label, "Journey", interchangeId, sjId); int stopPos = findStopPosition(interchangeId, label, "Point", sjId, pointRef); - return (trip == null || stopPos < 0) ? null : new TripTransferPoint(trip, stopPos); + return trip == null || stopPos < 0 ? null : new TripTransferPoint(trip, stopPos); } @Nullable diff --git a/application/src/main/java/org/opentripplanner/netex/support/stoptime/AbstractStopTimeAdaptor.java b/application/src/main/java/org/opentripplanner/netex/support/stoptime/AbstractStopTimeAdaptor.java index 9911cb98e2d..d5f22151f67 100644 --- a/application/src/main/java/org/opentripplanner/netex/support/stoptime/AbstractStopTimeAdaptor.java +++ b/application/src/main/java/org/opentripplanner/netex/support/stoptime/AbstractStopTimeAdaptor.java @@ -14,7 +14,8 @@ */ abstract sealed class AbstractStopTimeAdaptor implements StopTimeAdaptor - permits AreaStopTimeAdaptor, RegularStopTimeAdaptor { + permits AreaStopTimeAdaptor, RegularStopTimeAdaptor +{ private final TimetabledPassingTime timetabledPassingTime; diff --git a/application/src/main/java/org/opentripplanner/netex/validation/ServiceJourneyNonIncreasingPassingTime.java b/application/src/main/java/org/opentripplanner/netex/validation/ServiceJourneyNonIncreasingPassingTime.java index 383c9bbf681..0ad86fecbe1 100644 --- a/application/src/main/java/org/opentripplanner/netex/validation/ServiceJourneyNonIncreasingPassingTime.java +++ b/application/src/main/java/org/opentripplanner/netex/validation/ServiceJourneyNonIncreasingPassingTime.java @@ -28,7 +28,8 @@ * */ class ServiceJourneyNonIncreasingPassingTime - extends AbstractHMapValidationRule { + extends AbstractHMapValidationRule +{ private StopTimeAdaptor invalidTimetabledPassingTimeInfo; private ErrorType errorType; diff --git a/application/src/main/java/org/opentripplanner/osm/DefaultOsmProvider.java b/application/src/main/java/org/opentripplanner/osm/DefaultOsmProvider.java index 382ac67dc6c..3b08971baa4 100644 --- a/application/src/main/java/org/opentripplanner/osm/DefaultOsmProvider.java +++ b/application/src/main/java/org/opentripplanner/osm/DefaultOsmProvider.java @@ -9,7 +9,7 @@ import org.opentripplanner.datastore.api.FileType; import org.opentripplanner.datastore.file.FileDataSource; import org.opentripplanner.framework.application.OtpFileNames; -import org.opentripplanner.graph_builder.module.osm.OsmDatabase; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; import org.opentripplanner.osm.tagmapping.OsmTagMapper; import org.opentripplanner.osm.tagmapping.OsmTagMapperSource; import org.opentripplanner.osm.wayproperty.WayPropertySet; diff --git a/application/src/main/java/org/opentripplanner/osm/OsmOpeningHoursParser.java b/application/src/main/java/org/opentripplanner/osm/OsmOpeningHoursParser.java index 19e6df0c367..8f143b2820c 100644 --- a/application/src/main/java/org/opentripplanner/osm/OsmOpeningHoursParser.java +++ b/application/src/main/java/org/opentripplanner/osm/OsmOpeningHoursParser.java @@ -261,13 +261,15 @@ private OHCalendarBuilder.OpeningHoursBuilder setDateRangeForOpeningHoursBuilder return openingHoursBuilder; } DayOfWeek startDayOfWeek = DAY_OF_WEEK_MAP.getOrDefault(weekDayRange.getStartDay(), null); - DayOfWeek endDayOfWeek = weekDayRange.getEndDay() != null - ? DAY_OF_WEEK_MAP.getOrDefault(weekDayRange.getEndDay(), null) - : null; + DayOfWeek endDayOfWeek = + weekDayRange.getEndDay() != null + ? DAY_OF_WEEK_MAP.getOrDefault(weekDayRange.getEndDay(), null) + : null; java.time.Month startMonth = MONTH_MAP.getOrDefault(startDate.getMonth(), null); - java.time.Month endMonth = endDate != null && endDate.getMonth() != null - ? MONTH_MAP.getOrDefault(endDate.getMonth(), null) - : null; + java.time.Month endMonth = + endDate != null && endDate.getMonth() != null + ? MONTH_MAP.getOrDefault(endDate.getMonth(), null) + : null; openingHoursBuilder.on(startMonth, endMonth, startDayOfWeek, endDayOfWeek); } return openingHoursBuilder; @@ -501,20 +503,21 @@ private boolean is247Rule(Rule rule) { * Logs unhandled rule either with {@link Logger} or stores it in {@link DataImportIssueStore}. */ private void logUnhandled(Rule rule, String ohTag, String id, String link) { - var message = link != null - ? String.format( - "Rule %s is unhandled in the opening hours definition %s for %s (%s)", - rule, - ohTag, - id, - link - ) - : String.format( - "Rule %s is unhandled in the opening hours definition %s for %s", - rule, - ohTag, - id - ); + var message = + link != null + ? String.format( + "Rule %s is unhandled in the opening hours definition %s for %s (%s)", + rule, + ohTag, + id, + link + ) + : String.format( + "Rule %s is unhandled in the opening hours definition %s for %s", + rule, + ohTag, + id + ); if (issueStore != null) { issueStore.add("UnhandledOHRule", message); } else { diff --git a/application/src/main/java/org/opentripplanner/osm/OsmParser.java b/application/src/main/java/org/opentripplanner/osm/OsmParser.java index f23fba9c9b4..186a4b00eff 100644 --- a/application/src/main/java/org/opentripplanner/osm/OsmParser.java +++ b/application/src/main/java/org/opentripplanner/osm/OsmParser.java @@ -6,7 +6,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import org.opentripplanner.graph_builder.module.osm.OsmDatabase; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; import org.opentripplanner.osm.model.OsmMemberType; import org.opentripplanner.osm.model.OsmNode; import org.opentripplanner.osm.model.OsmNodeBuilder; diff --git a/application/src/main/java/org/opentripplanner/osm/OsmProvider.java b/application/src/main/java/org/opentripplanner/osm/OsmProvider.java index 9ebe21f16bd..606776fa690 100644 --- a/application/src/main/java/org/opentripplanner/osm/OsmProvider.java +++ b/application/src/main/java/org/opentripplanner/osm/OsmProvider.java @@ -1,7 +1,7 @@ package org.opentripplanner.osm; import java.time.ZoneId; -import org.opentripplanner.graph_builder.module.osm.OsmDatabase; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; import org.opentripplanner.osm.tagmapping.OsmTagMapper; import org.opentripplanner.osm.wayproperty.WayPropertySet; diff --git a/application/src/main/java/org/opentripplanner/osm/issues/FloorNumberUnknownAssumedGroundLevel.java b/application/src/main/java/org/opentripplanner/osm/issues/FloorNumberUnknownAssumedGroundLevel.java index 8274b13d5df..ff2bdda34af 100644 --- a/application/src/main/java/org/opentripplanner/osm/issues/FloorNumberUnknownAssumedGroundLevel.java +++ b/application/src/main/java/org/opentripplanner/osm/issues/FloorNumberUnknownAssumedGroundLevel.java @@ -3,8 +3,10 @@ import org.opentripplanner.graph_builder.issue.api.DataImportIssue; import org.opentripplanner.osm.model.OsmEntity; -public record FloorNumberUnknownAssumedGroundLevel(String level, OsmEntity entity) implements - DataImportIssue { +public record FloorNumberUnknownAssumedGroundLevel( + String level, + OsmEntity entity +) implements DataImportIssue { private static final String FMT = "%s : could not determine level from 'level' or 'layer' tag '%s', assumed to be ground-level."; diff --git a/application/src/main/java/org/opentripplanner/osm/model/CompoundRefTagGroup.java b/application/src/main/java/org/opentripplanner/osm/model/CompoundRefTagGroup.java new file mode 100644 index 00000000000..ba1c8ecbb6f --- /dev/null +++ b/application/src/main/java/org/opentripplanner/osm/model/CompoundRefTagGroup.java @@ -0,0 +1,83 @@ +package org.opentripplanner.osm.model; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * Represents a group of OpenStreetMap tags that together form a compound reference identifier for an entity. + *

+ * Tags provided at construction time are sanitized by stripping surrounding whitespace and + * filtering out null or blank values. The group can then produce a single compound value by + * mapping each tag to its corresponding value and joining the results with a colon delimiter. + *

+ * A compound value is only produced when all tags in the group resolve to a non-null value. + * If any tag cannot be resolved, the compound value is considered incomplete and absent. + *

+ * Instances are created via the factory method {@link #of(String...)}. + */ +public class CompoundRefTagGroup { + + private static final String DELIMITER = ":"; + + private final List tags; + + private CompoundRefTagGroup(String... tags) { + this.tags = Arrays.stream(tags) + .filter(Objects::nonNull) + .map(String::strip) + .filter(s -> !s.isEmpty()) + .toList(); + } + + public static CompoundRefTagGroup of(String... tags) { + return new CompoundRefTagGroup(tags); + } + + /** + * Produces a compound value by mapping each tag in this group to its corresponding value + * using the provided mapper function, then joining the results with a colon delimiter. + * + * The compound value is only produced when all tags in the group resolve to a non-null value + * via the mapper. If any tag maps to null, the result is considered incomplete and an empty + * Optional is returned. Each resolved value is stripped of surrounding whitespace before joining. + * + * @param tagToValueMapper a function that maps an OpenStreetMap tag name to its corresponding + * value, or null if the tag cannot be resolved + * @return an Optional containing the colon-delimited compound value if all tags resolved to + * non-null values, or an empty Optional if any tag could not be resolved + */ + public Optional compoundValue(Function tagToValueMapper) { + List values = tags.stream().map(tagToValueMapper).toList(); + if (values.stream().anyMatch(Objects::isNull)) { + return Optional.empty(); + } else { + return Optional.of(values.stream().map(String::strip).collect(Collectors.joining(DELIMITER))); + } + } + + @Override + public String toString() { + return "CompoundRefTagGroup{" + "tags=" + tags + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CompoundRefTagGroup that = (CompoundRefTagGroup) o; + return tags.equals(that.tags); + } + + @Override + public int hashCode() { + return Objects.hash(tags); + } +} diff --git a/application/src/main/java/org/opentripplanner/osm/model/OsmEntity.java b/application/src/main/java/org/opentripplanner/osm/model/OsmEntity.java index 18b3907c4d1..e0e85482811 100644 --- a/application/src/main/java/org/opentripplanner/osm/model/OsmEntity.java +++ b/application/src/main/java/org/opentripplanner/osm/model/OsmEntity.java @@ -13,6 +13,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -205,11 +206,11 @@ protected OsmEntity(long id, @Nullable Map tags, OsmProvider osm } public static boolean isFalse(String tagValue) { - return ("no".equals(tagValue) || "0".equals(tagValue) || "false".equals(tagValue)); + return "no".equals(tagValue) || "0".equals(tagValue) || "false".equals(tagValue); } public static boolean isTrue(String tagValue) { - return ("yes".equals(tagValue) || "1".equals(tagValue) || "true".equals(tagValue)); + return "yes".equals(tagValue) || "1".equals(tagValue) || "true".equals(tagValue); } /** @@ -585,7 +586,7 @@ public Map generateI18NForPattern(String pattern) { // get the translated value, if exists for (String lang : i18n.keySet()) { String i18nTag = getTag(defKey + ":" + lang); - i18n.get(lang).append(i18nTag != null ? i18nTag : (defTag != null ? defTag : "")); + i18n.get(lang).append(i18nTag != null ? i18nTag : defTag != null ? defTag : ""); } } for (StringBuffer sb : i18n.values()) { @@ -822,6 +823,21 @@ public Set getMultiTagValues(Set refTags) { return result; } + /** + * Combines the values of one or more tags into a single id, using the first of the given tag + * groups that resolves to a value. + *

+ * A group's tag values are joined with {@code :} in the given order. If any tag in a group is + * missing from this entity, that group is skipped in favor of the next one. A group with a + * single tag key produces a plain (non-compound) id. + */ + public Optional getCompoundTagValue(List tagGroups) { + return tagGroups + .stream() + .flatMap(tagGroup -> tagGroup.compoundValue(this::getTag).stream()) + .findFirst(); + } + public OsmProvider getOsmProvider() { return osmProvider; } @@ -866,7 +882,7 @@ public boolean isIndoorRoutable() { */ public boolean isLink() { String highway = getTag("highway"); - return highway != null && highway.endsWith(("_link")); + return highway != null && highway.endsWith("_link"); } public boolean isElevator() { diff --git a/application/src/main/java/org/opentripplanner/osm/tagmapping/NorwayMapper.java b/application/src/main/java/org/opentripplanner/osm/tagmapping/NorwayMapper.java index 18a2c393e00..2100a56ab16 100644 --- a/application/src/main/java/org/opentripplanner/osm/tagmapping/NorwayMapper.java +++ b/application/src/main/java/org/opentripplanner/osm/tagmapping/NorwayMapper.java @@ -35,38 +35,39 @@ public WayPropertySet buildWayPropertySet() { var hasSidewalk = new Condition.OneOf("sidewalk", "yes", "left", "right", "both"); // e.g sidewalk:left=yes var hasPrefixSidewalk = new Condition.Equals("sidewalk", "yes"); - props.setDefaultWalkSafetyForPermission((permission, speedLimit, way) -> - switch (permission) { - case ALL, PEDESTRIAN_AND_CAR -> { - if ( - hasSidewalk.isMatch(way) || - hasPrefixSidewalk.isLeftMatch(way) || - hasPrefixSidewalk.isRightMatch(way) - ) { - yield 1.1; - } - // 90 km/h or over - else if (speedLimit >= 25f) { - yield 3.; - } - // ~60 km/h or over - else if (speedLimit >= 16.6f) { - yield 1.9; - } - // ~40 km/h or over - else if (speedLimit >= 11.1f) { - yield 1.6; - } - // 30 km/h or lower - else { - yield 1.45; + props.setDefaultWalkSafetyForPermission( + (permission, speedLimit, way) -> + switch (permission) { + case ALL, PEDESTRIAN_AND_CAR -> { + if ( + hasSidewalk.isMatch(way) || + hasPrefixSidewalk.isLeftMatch(way) || + hasPrefixSidewalk.isRightMatch(way) + ) { + yield 1.1; + } + // 90 km/h or over + else if (speedLimit >= 25f) { + yield 3.; + } + // ~60 km/h or over + else if (speedLimit >= 16.6f) { + yield 1.9; + } + // ~40 km/h or over + else if (speedLimit >= 11.1f) { + yield 1.6; + } + // 30 km/h or lower + else { + yield 1.45; + } } + case PEDESTRIAN_AND_BICYCLE -> 1.15; + case PEDESTRIAN -> 1.; + // these don't include walking + case BICYCLE_AND_CAR, BICYCLE, CAR, NONE -> 3.; } - case PEDESTRIAN_AND_BICYCLE -> 1.15; - case PEDESTRIAN -> 1.; - // these don't include walking - case BICYCLE_AND_CAR, BICYCLE, CAR, NONE -> 3.; - } ); var cycleSafetyVeryHighTraffic = 10.; @@ -161,15 +162,16 @@ else if (speedLimit >= 11.1f) { } }; - props.setDefaultBicycleSafetyForPermission((permission, speedLimit, way) -> - switch (permission) { - case ALL -> cycleSafetyHighway.apply(speedLimit, way); - case BICYCLE_AND_CAR -> cycleSafetyVeryHighTraffic; - case PEDESTRIAN_AND_BICYCLE -> 1.12; - case BICYCLE -> 1.05; - // these don't include cycling - case PEDESTRIAN_AND_CAR, PEDESTRIAN, CAR, NONE -> cycleSafetyVeryHighTraffic; - } + props.setDefaultBicycleSafetyForPermission( + (permission, speedLimit, way) -> + switch (permission) { + case ALL -> cycleSafetyHighway.apply(speedLimit, way); + case BICYCLE_AND_CAR -> cycleSafetyVeryHighTraffic; + case PEDESTRIAN_AND_BICYCLE -> 1.12; + case BICYCLE -> 1.05; + // these don't include cycling + case PEDESTRIAN_AND_CAR, PEDESTRIAN, CAR, NONE -> cycleSafetyVeryHighTraffic; + } ); props.setProperties( @@ -641,7 +643,7 @@ else if (speedLimit >= 11.1f) { // 110 km/h props.setMaxPossibleCarSpeed(30.56f); - super.populateNotesAndNames(props); + super.populateNames(props); props.setSlopeOverride(new BestMatchSpecifier("bridge=*"), true); props.setSlopeOverride(new BestMatchSpecifier("cutting=*"), true); diff --git a/application/src/main/java/org/opentripplanner/osm/tagmapping/OsmTagMapper.java b/application/src/main/java/org/opentripplanner/osm/tagmapping/OsmTagMapper.java index c84ea12663b..c056ac9b8f9 100644 --- a/application/src/main/java/org/opentripplanner/osm/tagmapping/OsmTagMapper.java +++ b/application/src/main/java/org/opentripplanner/osm/tagmapping/OsmTagMapper.java @@ -23,7 +23,6 @@ import org.opentripplanner.osm.wayproperty.specifier.Condition.Not; import org.opentripplanner.osm.wayproperty.specifier.ExactMatchSpecifier; import org.opentripplanner.osm.wayproperty.specifier.LogicalOrSpecifier; -import org.opentripplanner.street.internal.notes.StreetNotesService; /** * This factory class provides a default collection of {@link WayProperties} that determine how OSM @@ -407,7 +406,7 @@ public WayPropertySet buildWayPropertySet() { ofBicycleSafety(2) ); - populateNotesAndNames(props); + populateNames(props); // slope overrides props.setSlopeOverride(new BestMatchSpecifier("bridge=*"), true); @@ -420,40 +419,7 @@ public WayPropertySet buildWayPropertySet() { return props.build(); } - static void populateNotesAndNames(WayPropertySetBuilder props) { - /* and the notes */ - // TODO: The curly brackets in the string below mean that the CreativeNamer should substitute in OSM tag values. - // However they are not taken into account when passed to the translation function. - // props.createNotes("wheelchair:description=*", "{wheelchair:description}", StreetNotesService.WHEELCHAIR_MATCHER); - // TODO: The two entries below produce lots of spurious notes (because of OSM mapper comments) - // props.createNotes("note=*", "{note}", StreetNotesService.ALWAYS_MATCHER); - // props.createNotes("notes=*", "{notes}", StreetNotesService.ALWAYS_MATCHER); - props.createNotes( - "RLIS:bicycle=caution_area", - "note.caution", - StreetNotesService.BICYCLE_MATCHER - ); - props.createNotes( - "CCGIS:bicycle=caution_area", - "note.caution", - StreetNotesService.BICYCLE_MATCHER - ); - // TODO: Maybe we should apply the following notes only for car/bike - props.createNotes("surface=unpaved", "note.unpaved_surface", StreetNotesService.ALWAYS_MATCHER); - props.createNotes( - "surface=compacted", - "note.unpaved_surface", - StreetNotesService.ALWAYS_MATCHER - ); - props.createNotes("surface=ground", "note.unpaved_surface", StreetNotesService.ALWAYS_MATCHER); - props.createNotes("surface=dirt", "note.unpaved_surface", StreetNotesService.ALWAYS_MATCHER); - props.createNotes("surface=earth", "note.unpaved_surface", StreetNotesService.ALWAYS_MATCHER); - props.createNotes("surface=grass", "note.unpaved_surface", StreetNotesService.ALWAYS_MATCHER); - props.createNotes("surface=mud", "note.muddy_surface", StreetNotesService.ALWAYS_MATCHER); - props.createNotes("toll=yes", "note.toll", StreetNotesService.DRIVING_MATCHER); - props.createNotes("toll:motorcar=yes", "note.toll", StreetNotesService.DRIVING_MATCHER); - - /* and some names */ + static void populateNames(WayPropertySetBuilder props) { // Basics props.createNames("highway=cycleway", "name.bike_path"); props.createNames("cycleway=track", "name.bike_path"); diff --git a/application/src/main/java/org/opentripplanner/osm/wayproperty/NotePicker.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/NotePicker.java deleted file mode 100644 index 9dedefe5667..00000000000 --- a/application/src/main/java/org/opentripplanner/osm/wayproperty/NotePicker.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.opentripplanner.osm.wayproperty; - -import org.opentripplanner.osm.wayproperty.specifier.OsmSpecifier; - -/** - * Defines which OSM ways get notes and what kind of notes they get. - * - * @author novalis - */ -public record NotePicker(OsmSpecifier specifier, NoteProperties noteProperties) {} diff --git a/application/src/main/java/org/opentripplanner/osm/wayproperty/NoteProperties.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/NoteProperties.java deleted file mode 100644 index 78ead4914cb..00000000000 --- a/application/src/main/java/org/opentripplanner/osm/wayproperty/NoteProperties.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.opentripplanner.osm.wayproperty; - -import java.util.Map; -import java.util.regex.Pattern; -import org.opentripplanner.core.model.i18n.I18NString; -import org.opentripplanner.core.model.i18n.TranslatedString; -import org.opentripplanner.osm.model.OsmEntity; -import org.opentripplanner.street.model.note.StreetNote; -import org.opentripplanner.street.model.note.StreetNoteAndMatcher; -import org.opentripplanner.street.model.note.StreetNoteMatcher; - -public class NoteProperties { - - private static final Pattern PATTERN_MATCHER = Pattern.compile("\\{(.*?)}"); - - private final String notePattern; - - private final StreetNoteMatcher noteMatcher; - - public NoteProperties(String notePattern, StreetNoteMatcher noteMatcher) { - this.notePattern = notePattern; - this.noteMatcher = noteMatcher; - } - - public StreetNoteAndMatcher generateNote(OsmEntity way) { - I18NString text; - //TODO: this could probably be made without patternMatch for {} since all notes (at least currently) have {note} as notePattern - if (PATTERN_MATCHER.matcher(notePattern).matches()) { - //This gets language -> translation of notePattern and all tags (which can have translations name:en for example) - Map noteText = way.generateI18NForPattern(notePattern); - text = TranslatedString.getDeduplicatedI18NString(noteText, false); - } else { - text = LocalizedStringMapper.getInstance().map(notePattern, way); - } - StreetNote note = new StreetNote(text); - - return new StreetNoteAndMatcher(note, noteMatcher); - } -} diff --git a/application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertySet.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertySet.java index aa3e80081eb..6898834f91b 100644 --- a/application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertySet.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertySet.java @@ -5,9 +5,7 @@ import static org.opentripplanner.osm.model.TraverseDirection.FORWARD; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; import org.opentripplanner.core.model.i18n.I18NString; import org.opentripplanner.framework.functional.FunctionUtils.TriFunction; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; @@ -16,7 +14,6 @@ import org.opentripplanner.osm.model.TraverseDirection; import org.opentripplanner.osm.wayproperty.specifier.OsmSpecifier; import org.opentripplanner.street.model.StreetTraversalPermission; -import org.opentripplanner.street.model.note.StreetNoteAndMatcher; /** * Information given to the GraphBuilder about how to assign permissions, safety values, names, etc. @@ -34,14 +31,14 @@ public class WayPropertySet { Float, OsmEntity, Double - > DEFAULT_BICYCLE_SAFETY_RESOLVER = ((permission, speedLimit, osmWay) -> 1.0); + > DEFAULT_BICYCLE_SAFETY_RESOLVER = (permission, speedLimit, osmWay) -> 1.0; public static final TriFunction< StreetTraversalPermission, Float, OsmEntity, Double - > DEFAULT_WALK_SAFETY_RESOLVER = ((permission, speedLimit, osmWay) -> 1.25); + > DEFAULT_WALK_SAFETY_RESOLVER = (permission, speedLimit, osmWay) -> 1.25; private final List wayProperties; @@ -53,8 +50,6 @@ public class WayPropertySet { /** Assign automobile speeds based on OSM tags. */ private final List speedPickers; - private final List notes; - private final List mixins; /** The automobile speed for street segments that do not match any SpeedPicker. */ @@ -90,7 +85,6 @@ public class WayPropertySet { this.creativeNamers = List.copyOf(builder.creativeNamers); this.slopeOverrides = List.copyOf(builder.slopeOverrides); this.speedPickers = List.copyOf(builder.speedPickers); - this.notes = List.copyOf(builder.notes); this.mixins = List.copyOf(builder.mixins); this.defaultCarSpeed = builder.defaultCarSpeed; this.maxPossibleCarSpeed = builder.maxPossibleCarSpeed; @@ -287,18 +281,6 @@ public float getCarSpeedForWay( } } - public Set getNoteForWay(OsmEntity way) { - HashSet out = new HashSet<>(); - for (NotePicker picker : notes) { - OsmSpecifier specifier = picker.specifier(); - NoteProperties noteProperties = picker.noteProperties(); - if (specifier.matchScore(way, DIRECTIONLESS) > 0) { - out.add(noteProperties.generateNote(way)); - } - } - return out; - } - public boolean getSlopeOverride(OsmEntity way) { boolean result = false; int bestScore = 0; @@ -330,8 +312,7 @@ public boolean equals(Object o) { defaultProperties.equals(other.defaultProperties) && wayProperties.equals(other.wayProperties) && creativeNamers.equals(other.creativeNamers) && - slopeOverrides.equals(other.slopeOverrides) && - notes.equals(other.notes) + slopeOverrides.equals(other.slopeOverrides) ); } return false; @@ -357,10 +338,6 @@ public List listSpeedPickers() { return speedPickers; } - public List listNotes() { - return notes; - } - private WayProperties applyMixins( WayProperties result, List mixins, diff --git a/application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertySetBuilder.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertySetBuilder.java index 708b1dc8bb4..86c99836230 100644 --- a/application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertySetBuilder.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertySetBuilder.java @@ -10,7 +10,6 @@ import org.opentripplanner.osm.wayproperty.specifier.BestMatchSpecifier; import org.opentripplanner.osm.wayproperty.specifier.OsmSpecifier; import org.opentripplanner.street.model.StreetTraversalPermission; -import org.opentripplanner.street.model.note.StreetNoteMatcher; public class WayPropertySetBuilder { @@ -21,7 +20,6 @@ public class WayPropertySetBuilder { final List creativeNamers = new ArrayList<>(); final List slopeOverrides = new ArrayList<>(); final List speedPickers = new ArrayList<>(); - final List notes = new ArrayList<>(); final List mixins = new ArrayList<>(); FunctionUtils.TriFunction< StreetTraversalPermission, @@ -61,10 +59,6 @@ public void addCreativeNamer(OsmSpecifier spec, CreativeNamer namer) { creativeNamers.add(new CreativeNamerPicker(spec, namer)); } - public void addNote(OsmSpecifier osmSpecifier, NoteProperties properties) { - notes.add(new NotePicker(osmSpecifier, properties)); - } - public void setSlopeOverride(OsmSpecifier spec, boolean override) { slopeOverrides.add(new SlopeOverridePicker(spec, override)); } @@ -78,12 +72,6 @@ public void createNames(String spec, String patternKey) { addCreativeNamer(new BestMatchSpecifier(spec), namer); } - public void createNotes(String spec, String patternKey, StreetNoteMatcher matcher) { - // TODO: notes aren't localized - NoteProperties properties = new NoteProperties(patternKey, matcher); - addNote(new BestMatchSpecifier(spec), properties); - } - public void setDefaultWalkSafetyForPermission( FunctionUtils.TriFunction< StreetTraversalPermission, @@ -182,7 +170,6 @@ public WayPropertySetBuilder addPickers(WayPropertySet other) { this.creativeNamers.addAll(other.listCreativeNamers()); this.slopeOverrides.addAll(other.listSlopeOverrides()); this.speedPickers.addAll(other.listSpeedPickers()); - this.notes.addAll(other.listNotes()); this.mixins.addAll(other.listMixins()); return this; } diff --git a/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/Condition.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/Condition.java index 8bee22bab8e..b45b0e05740 100644 --- a/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/Condition.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/Condition.java @@ -259,9 +259,7 @@ public OneOfOrAbsent(String key) { @Override public boolean isExtendedKeyMatch(OsmEntity way, String exKey) { - return ( - !way.hasTag(exKey) || Arrays.stream(values).anyMatch(value -> way.isTag(exKey, value)) - ); + return !way.hasTag(exKey) || Arrays.stream(values).anyMatch(value -> way.isTag(exKey, value)); } @Override diff --git a/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/LogicalOrSpecifier.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/LogicalOrSpecifier.java index 149d33c89a6..b37356416c9 100644 --- a/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/LogicalOrSpecifier.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/LogicalOrSpecifier.java @@ -33,15 +33,14 @@ public LogicalOrSpecifier(String... specs) { @Override public int matchScore(OsmEntity way, TraverseDirection direction) { - var oneMatchesExactly = subSpecs - .stream() - .anyMatch(subspec -> + var oneMatchesExactly = subSpecs.stream().anyMatch( + subspec -> switch (direction) { case DIRECTIONLESS -> subspec.allTagsMatch(way); case FORWARD -> subspec.allForwardTagsMatch(way); case BACKWARD -> subspec.allBackwardTagsMatch(way); } - ); + ); if (oneMatchesExactly) { return 1; } else { diff --git a/application/src/main/java/org/opentripplanner/place/api/NearbyStop.java b/application/src/main/java/org/opentripplanner/place/api/NearbyStop.java index b5d6407100a..7ed01d94aa9 100644 --- a/application/src/main/java/org/opentripplanner/place/api/NearbyStop.java +++ b/application/src/main/java/org/opentripplanner/place/api/NearbyStop.java @@ -63,9 +63,9 @@ public int compareTo(NearbyStop that) { } if (this.state != null) { - return (int) (this.state.getWeight()) - (int) (that.state.getWeight()); + return (int) this.state.getWeight() - (int) that.state.getWeight(); } - return (int) (this.distance) - (int) (that.distance); + return (int) this.distance - (int) that.distance; } /** diff --git a/application/src/main/java/org/opentripplanner/place/placefinder/PlaceFinderTraverseVisitor.java b/application/src/main/java/org/opentripplanner/place/placefinder/PlaceFinderTraverseVisitor.java index a3b180ca7eb..9e3ce3124cd 100644 --- a/application/src/main/java/org/opentripplanner/place/placefinder/PlaceFinderTraverseVisitor.java +++ b/application/src/main/java/org/opentripplanner/place/placefinder/PlaceFinderTraverseVisitor.java @@ -189,9 +189,7 @@ private boolean stopIsIncludedByStopFilter(RegularStop stop) { } private boolean stopIsIncludedByStationFilter(RegularStop stop) { - return ( - ((filterByStations.isEmpty() || filterByStations.contains(stop.getParentStation().getId()))) - ); + return filterByStations.isEmpty() || filterByStations.contains(stop.getParentStation().getId()); } private boolean stopIsIncludedByModeFilter(RegularStop stop) { diff --git a/application/src/main/java/org/opentripplanner/routing/alertpatch/AlertCalendar.java b/application/src/main/java/org/opentripplanner/routing/alertpatch/AlertCalendar.java index d7ab993559c..7ae8c3277a8 100644 --- a/application/src/main/java/org/opentripplanner/routing/alertpatch/AlertCalendar.java +++ b/application/src/main/java/org/opentripplanner/routing/alertpatch/AlertCalendar.java @@ -10,12 +10,12 @@ import org.opentripplanner.utils.tostring.ToStringBuilder; /** - * The validity of an alert, expressed as a set of {@link TimePeriod}s. The alert is valid if any of - * the periods is valid, which means that an empty calendar is never valid. + * The validity of an alert, expressed as a non-empty set of {@link TimePeriod}s. The alert is valid + * if any of the periods are valid. An alert always has at least one period: if the source data does + * not contain any validity information, the alert is {@link #ofAlwaysActive() always active}. */ public final class AlertCalendar { - private static final AlertCalendar NEVER_ACTIVE = new AlertCalendar(List.of()); private static final AlertCalendar ALWAYS_ACTIVE = new AlertCalendar( List.of(TimePeriod.ofUnbounded()) ); @@ -27,7 +27,13 @@ private AlertCalendar(Collection timePeriods) { } public static AlertCalendar of(Collection timePeriods) { - return timePeriods.isEmpty() ? NEVER_ACTIVE : new AlertCalendar(timePeriods); + if (timePeriods.isEmpty()) { + throw new IllegalArgumentException( + "An alert calendar must have at least one time period. Use ofAlwaysActive() if the alert " + + "has no validity information." + ); + } + return new AlertCalendar(timePeriods); } public static AlertCalendar of(TimePeriod... timePeriods) { @@ -41,21 +47,10 @@ public static AlertCalendar ofAlwaysActive() { return ALWAYS_ACTIVE; } - /** - * A calendar without any time periods, which is never valid. - */ - public static AlertCalendar ofNeverActive() { - return NEVER_ACTIVE; - } - public Collection timePeriods() { return timePeriods; } - public boolean isNeverActive() { - return timePeriods.isEmpty(); - } - /** * Returns {@code true} if any of the time periods overlaps the given {@code period}. */ @@ -71,10 +66,10 @@ public boolean isActiveAt(Instant instant) { } /** - * The earliest start of all time periods, or empty if any period has an open start. + * The earliest start of all time periods, or empty if any period has an unbounded start. */ public Optional effectiveStart() { - if (timePeriods.stream().anyMatch(TimePeriod::hasOpenStart)) { + if (timePeriods.stream().anyMatch(TimePeriod::hasUnboundedStart)) { return Optional.empty(); } return timePeriods @@ -85,10 +80,10 @@ public Optional effectiveStart() { } /** - * The latest end of all time periods, or empty if any period is open-ended. + * The latest end of all time periods, or empty if any period has an unbounded end. */ public Optional effectiveEnd() { - if (timePeriods.stream().anyMatch(TimePeriod::hasOpenEnd)) { + if (timePeriods.stream().anyMatch(TimePeriod::hasUnboundedEnd)) { return Optional.empty(); } return timePeriods diff --git a/application/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlert.java b/application/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlert.java index 41767ec8ff2..7ee1b925aac 100644 --- a/application/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlert.java +++ b/application/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlert.java @@ -185,7 +185,7 @@ public boolean isActiveAt(Instant instant) { /** * Finds the first validity start from all timePeriods for this alert. * - * @return First start for this Alert, null if any period has an open start + * @return First start for this Alert, null if any period has an unbounded start */ @Nullable public Instant getEffectiveStartDate() { @@ -194,9 +194,9 @@ public Instant getEffectiveStartDate() { /** * Finds the last validity end from all timePeriods for this alert. Returns null - * if the validity is open-ended + * if any period has an unbounded end. * - * @return Last end for this Alert, null if open-ended + * @return Last end for this Alert, null if any period has an unbounded end */ @Nullable public Instant getEffectiveEndDate() { diff --git a/application/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlertBuilder.java b/application/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlertBuilder.java index 01329191027..4fa0965033a 100644 --- a/application/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlertBuilder.java +++ b/application/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlertBuilder.java @@ -29,7 +29,8 @@ public class TransitAlertBuilder extends AbstractEntityBuilder entities = new HashSet<>(); - private AlertCalendar calendar = AlertCalendar.ofNeverActive(); + /** If the source data has no validity information, the alert is always active. */ + private AlertCalendar calendar = AlertCalendar.ofAlwaysActive(); TransitAlertBuilder(FeedScopedId id) { super(id); diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/RequestPreProcessor.java b/application/src/main/java/org/opentripplanner/routing/algorithm/RequestPreProcessor.java index 39380053b38..c3f0cff701c 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/RequestPreProcessor.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/RequestPreProcessor.java @@ -86,12 +86,13 @@ private RouteRequest prepareRequestForStartOnBoardAccess(RouteRequest request) { tripLocation.tripOnDateReference() ); var aimedDeparture = tripLocation.aimedDepartureTime(); - Integer aimedDepartureSeconds = aimedDeparture == null - ? null - : ServiceDateUtils.secondsSinceStartOfTime( - ServiceDateUtils.asStartOfService(tripAndServiceDate.serviceDate(), zoneId), - aimedDeparture - ); + Integer aimedDepartureSeconds = + aimedDeparture == null + ? null + : ServiceDateUtils.secondsSinceStartOfTime( + ServiceDateUtils.asStartOfService(tripAndServiceDate.serviceDate(), zoneId), + aimedDeparture + ); var locationInTripPattern = new TripLocationResolver(transitService).resolve( tripAndServiceDate, tripLocation.stopLocationId(), diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalking.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalking.java index 50a658d40a5..c0a484df3a7 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalking.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalking.java @@ -41,7 +41,7 @@ public Predicate shouldBeFlaggedForRemoval() { double totalDistance = itinerary.distanceMeters(); return ( - bikeRentalDistance != 0 && (bikeRentalDistance / totalDistance) <= bikeRentalDistanceRatio + bikeRentalDistance != 0 && bikeRentalDistance / totalDistance <= bikeRentalDistanceRatio ); }; } diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingFilter.java index c966974c805..16ffdf15eb6 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingFilter.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingFilter.java @@ -45,7 +45,7 @@ public Predicate shouldBeFlaggedForRemoval() { .sum(); double totalDuration = itinerary.totalDuration().toSeconds(); - return (carDuration != 0 && (carDuration / totalDuration) <= parkAndRideDurationRatio); + return carDuration != 0 && carDuration / totalDuration <= parkAndRideDurationRatio; }; } diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/AlertToLegMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/AlertToLegMapper.java index 0f9103a864e..c52e0f6880c 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/AlertToLegMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/AlertToLegMapper.java @@ -129,8 +129,9 @@ public TransitLeg decorateWithAlerts(TransitLeg leg, boolean isFirstLeg) { totalAlerts.addAll(filterAlertsByTime(alerts, legStartTime, legEndTime)); // Filter alerts when there are multiple timePeriods for each alert - totalAlerts.removeIf(alert -> - !alert.isActiveDuring(TimePeriod.of(leg.startTime().toInstant(), leg.endTime().toInstant())) + totalAlerts.removeIf( + alert -> + !alert.isActiveDuring(TimePeriod.of(leg.startTime().toInstant(), leg.endTime().toInstant())) ); if (totalAlerts.isEmpty()) { diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java index a9530437124..501a589839e 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java @@ -26,7 +26,9 @@ public static PagingService createPagingService( transitTuningParameters.pagingSearchWindowAdjustments(), // The dynamic search-window is not the same as requested search-window, but in lack // of a something else we use the raptor dynamic min here. - raptorTuningParameters.dynamicSearchWindowCoefficients().minWindow(), + raptorTuningParameters + .dynamicSearchWindowCoefficients() + .minWindow(), transitTuningParameters.maxSearchWindow(), searchWindowOf(raptorSearchParamsUsed), edt(searchStartTime, raptorSearchParamsUsed), diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java index bf41fd0a1fc..ceffaf4620e 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java @@ -98,7 +98,6 @@ public RaptorPathToItineraryMapper( this.streetPathToLegsMapper = new StreetPathToLegsMapper( new TransitServiceResolver(transitService), transitService.getTimeZone(), - graph.streetNotesService, streetDetailsService, graph.ellipsoidToGeoidDifference ); @@ -195,7 +194,7 @@ private static boolean isPathTransferAtSameStop( previousLeg.isTransitLeg() && currentLeg.isTransitLeg() && !previousLeg.asTransitLeg().isStaySeatedOntoNextLeg() && - (previousLeg.asTransitLeg().toStop() == currentLeg.asTransitLeg().fromStop()) + previousLeg.asTransitLeg().toStop() == currentLeg.asTransitLeg().fromStop() ); } @@ -242,7 +241,7 @@ private Leg mapTransitLeg(Leg prevTransitLeg, TransitPathLeg pathLeg) { .withServiceDate(tripSchedule.getServiceDate()) .withZoneId(transitSearchTimeZero.getZone().normalized()) .withTransferFromPreviousLeg( - (prevTransitLeg == null ? null : prevTransitLeg.transferToNextLeg()) + prevTransitLeg == null ? null : prevTransitLeg.transferToNextLeg() ) .withTransferToNextLeg((ConstrainedTransfer) pathLeg.getConstrainedTransferAfterLeg()) .withGeneralizedCost(toOtpDomainCost(pathLeg.c1() + lastLegCost)) @@ -275,7 +274,7 @@ private Leg mapTransitLeg(Leg prevTransitLeg, TransitPathLeg pathLeg) { .withZoneId(transitSearchTimeZero.getZone().normalized()) .withTripOnServiceDate(tripOnServiceDate) .withTransferFromPreviousLeg( - (prevTransitLeg == null ? null : prevTransitLeg.transferToNextLeg()) + prevTransitLeg == null ? null : prevTransitLeg.transferToNextLeg() ) .withTransferToNextLeg((ConstrainedTransfer) pathLeg.getConstrainedTransferAfterLeg()) .withGeneralizedCost(toOtpDomainCost(pathLeg.c1() + lastLegCost)) diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java index 7340deb3a34..5a732c75c9d 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java @@ -22,7 +22,6 @@ import org.opentripplanner.service.streetdetails.StreetDetailsService; import org.opentripplanner.street.geometry.DirectionUtils; import org.opentripplanner.street.geometry.WgsCoordinate; -import org.opentripplanner.street.internal.notes.StreetNotesService; import org.opentripplanner.street.model.edge.AreaEdge; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.edge.ElevatorAlightEdge; @@ -55,7 +54,6 @@ public class StatesToWalkStepsMapper { ); private final double ellipsoidToGeoidDifference; - private final StreetNotesService streetNotesService; private final VerticalTransportationUseFactory verticalTransportationUseFactory; private final List states; @@ -86,14 +84,12 @@ public class StatesToWalkStepsMapper { public StatesToWalkStepsMapper( List states, WalkStep previousStep, - StreetNotesService streetNotesService, StreetDetailsService streetDetailsService, EntranceResolver entranceResolver, double ellipsoidToGeoidDifference ) { this.states = states; this.previous = previousStep; - this.streetNotesService = streetNotesService; this.entranceResolver = entranceResolver; this.ellipsoidToGeoidDifference = ellipsoidToGeoidDifference; this.verticalTransportationUseFactory = new VerticalTransportationUseFactory( @@ -155,7 +151,7 @@ private static double getAbsoluteAngleDiff(double thisAngle, double lastAngle) { } private static boolean isLink(Edge edge) { - return (edge instanceof StreetEdge streetEdge && streetEdge.isLink()); + return edge instanceof StreetEdge streetEdge && streetEdge.isLink(); } private static ElevationProfile encodeElevationProfile( @@ -237,8 +233,7 @@ private void processState(State backState, State forwardState) { modeTransition || !continueOnSameStreet(edge, streetNameNoParens) || // went on to or off of a roundabout - edge.isRoundabout() != - (roundaboutExit > 0) || + edge.isRoundabout() != roundaboutExit > 0 || (isLink(edge) && !isLink(backState.getBackEdge())) ) { // Street name has changed, or we've gone on to or off of a roundabout. @@ -329,9 +324,7 @@ private void processState(State backState, State forwardState) { } // increment the total length for this step - current - .addDistance(edge.getDistanceMeters()) - .addStreetNotes(streetNotesService.getNotes(forwardState)); + current.addDistance(edge.getDistanceMeters()); lastAngle = DirectionUtils.getLastAngle(geom); current.addEdge(edge); @@ -506,7 +499,7 @@ private boolean isTurnToOtherStreet(String streetName, double angleDiff, Edge al private boolean continueOnSameStreet(Edge edge, String streetNameNoParens) { return !( current.directionText().toString() != null && - !(java.util.Objects.equals(current.directionTextNoParens(), streetNameNoParens)) && + !java.util.Objects.equals(current.directionTextNoParens(), streetNameNoParens) && (!current.nameIsDerived() || !edge.nameIsDerived()) ); } @@ -693,7 +686,6 @@ private WalkStepBuilder createWalkStep(State forwardState, State backState) { 0, forwardState.getRequest().geoidElevation() ? -ellipsoidToGeoidDifference : 0 ) - ) - .addStreetNotes(streetNotesService.getNotes(forwardState)); + ); } } diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StreetPathToLegsMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StreetPathToLegsMapper.java index ff112ebc823..eed4e0a44b8 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StreetPathToLegsMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StreetPathToLegsMapper.java @@ -9,7 +9,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Objects; -import java.util.Set; import javax.annotation.Nullable; import org.opentripplanner.core.model.i18n.I18NString; import org.opentripplanner.ext.flex.FlexibleTransitLeg; @@ -26,9 +25,7 @@ import org.opentripplanner.service.streetdetails.StreetDetailsService; import org.opentripplanner.service.vehiclerental.street.VehicleRentalEdge; import org.opentripplanner.service.vehiclerental.street.VehicleRentalPlaceVertex; -import org.opentripplanner.street.internal.notes.StreetNotesService; import org.opentripplanner.street.model.edge.VehicleParkingEdge; -import org.opentripplanner.street.model.note.StreetNote; import org.opentripplanner.street.model.path.StreetPath; import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.street.model.vertex.TemporaryStreetLocation; @@ -50,20 +47,17 @@ public class StreetPathToLegsMapper { private final SiteResolver siteResolver; private final ZoneId timeZone; - private final StreetNotesService streetNotesService; private final StreetDetailsService streetDetailsService; private final double ellipsoidToGeoidDifference; public StreetPathToLegsMapper( SiteResolver siteResolver, ZoneId timeZone, - StreetNotesService streetNotesService, StreetDetailsService streetDetailsService, double ellipsoidToGeoidDifference ) { this.siteResolver = siteResolver; this.timeZone = ZoneIdFallback.zoneId(timeZone); - this.streetNotesService = streetNotesService; this.streetDetailsService = streetDetailsService; this.ellipsoidToGeoidDifference = ellipsoidToGeoidDifference; } @@ -88,8 +82,8 @@ public static boolean isRentalStationDropOff(State state) { public static boolean isFloatingRentalDropoff(State state) { return ( !state.isRentingVehicle() && - (state.getBackState() != null && - state.getBackState().getVehicleRentalState() == RENTING_FLOATING) + state.getBackState() != null && + state.getBackState().getVehicleRentalState() == RENTING_FLOATING ); } @@ -128,9 +122,8 @@ public List map( if (subPaths.isEmpty()) { return List.of(); } - var delay = startTime != null - ? Duration.between(subPaths.getFirst().startTime(), startTime) - : null; + var delay = + startTime != null ? Duration.between(subPaths.getFirst().startTime(), startTime) : null; for (var subPath : subPaths) { if ( OTPFeature.FlexRouting.isOn() && subPath.states().get(1).backEdge instanceof FlexTripEdge @@ -215,28 +208,30 @@ private static List slicePath(StreetPath streetPath) { * @param states The states that go with the leg */ private static TraverseMode resolveMode(List states) { - return states - .stream() - // The first state is part of the previous leg - .skip(1) - .map(state -> { - var mode = state.currentMode(); - - if (mode != null) { - // Resolve correct mode if renting vehicle - if (state.isRentingVehicle()) { - return state.stateData.rentalVehicleFormFactor.traverseMode; - } else { - return mode; + return ( + states + .stream() + // The first state is part of the previous leg + .skip(1) + .map(state -> { + var mode = state.currentMode(); + + if (mode != null) { + // Resolve correct mode if renting vehicle + if (state.isRentingVehicle()) { + return state.stateData.rentalVehicleFormFactor.traverseMode; + } else { + return mode; + } } - } - return null; - }) - .filter(Objects::nonNull) - .findFirst() - // Fallback to walking - .orElse(TraverseMode.WALK); + return null; + }) + .filter(Objects::nonNull) + .findFirst() + // Fallback to walking + .orElse(TraverseMode.WALK) + ); } /** @@ -316,7 +311,6 @@ private StreetLeg generateLeg( var statesToWalkStepsMapper = new StatesToWalkStepsMapper( states, previousStep, - streetNotesService, streetDetailsService, siteResolver, ellipsoidToGeoidDifference @@ -357,27 +351,9 @@ private StreetLeg generateLeg( } } - addStreetNotes(leg, states); - return leg.build(); } - /** - * Add mode and alerts fields to a {@link StreetLeg}. - * - * @param leg The leg to add the mode and alerts to - * @param states The states that go with the leg - */ - private void addStreetNotes(StreetLegBuilder leg, List states) { - for (State state : states) { - Set streetNotes = streetNotesService.getNotes(state); - - if (streetNotes != null) { - leg.withStreetNotes(streetNotes); - } - } - } - private ZonedDateTime getTimeWithDelay(State state, @Nullable Duration delay) { if (delay != null) { return state.getTime().atZone(timeZone).plus(delay); diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/ViaLocationTypeMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/ViaLocationTypeMapper.java index 5f4365e3dff..e1b2beb833e 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/ViaLocationTypeMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/ViaLocationTypeMapper.java @@ -42,14 +42,12 @@ public static ViaLocationType map( List viaLocations, TemporaryStreetLocation location ) { - var isViaLocation = viaLocations - .stream() - .anyMatch(viaLocation -> - viaLocation - .coordinate() - .stream() - .anyMatch(coordinate -> coordinate.asJtsCoordinate().equals(location.getCoordinate())) - ); + var isViaLocation = viaLocations.stream().anyMatch(viaLocation -> + viaLocation + .coordinate() + .stream() + .anyMatch(coordinate -> coordinate.asJtsCoordinate().equals(location.getCoordinate())) + ); return isViaLocation ? ViaLocationType.VISIT : null; } } diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/path/PathDiff.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/path/PathDiff.java index d323ee1e12f..5134605d41b 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/path/PathDiff.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/path/PathDiff.java @@ -101,8 +101,14 @@ public static List>> diff( boolean skipCost ) { return DiffTool.diff( - left.stream().map(PathDiff::new).collect(Collectors.toList()), - right.stream().map(PathDiff::new).collect(Collectors.toList()), + left + .stream() + .map(PathDiff::new) + .collect(Collectors.toList()), + right + .stream() + .map(PathDiff::new) + .collect(Collectors.toList()), comparator(skipCost) ); } diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/AccessEgressFetcher.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/AccessEgressFetcher.java index 99ebc55a80c..1812e5da80e 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/AccessEgressFetcher.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/AccessEgressFetcher.java @@ -130,15 +130,16 @@ RoutingStartOnBoardAccess fetchStartOnBoardAccess() { onBoardTripLocation.tripOnDateReference() ); var aimedDeparture = onBoardTripLocation.aimedDepartureTime(); - Integer aimedDepartureSeconds = aimedDeparture == null - ? null - : ServiceDateUtils.secondsSinceStartOfTime( - ServiceDateUtils.asStartOfService( - tripAndServiceDate.serviceDate(), - transitService.getTimeZone() - ), - aimedDeparture - ); + Integer aimedDepartureSeconds = + aimedDeparture == null + ? null + : ServiceDateUtils.secondsSinceStartOfTime( + ServiceDateUtils.asStartOfService( + tripAndServiceDate.serviceDate(), + transitService.getTimeZone() + ), + aimedDeparture + ); var tripLocation = tripLocationResolver.resolve( tripAndServiceDate, onBoardTripLocation.stopLocationId(), diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/performance/PerformanceTimersForRaptor.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/performance/PerformanceTimersForRaptor.java index 2b46647bde6..8483f5cef72 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/performance/PerformanceTimersForRaptor.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/performance/PerformanceTimersForRaptor.java @@ -24,7 +24,9 @@ public PerformanceTimersForRaptor( this.registry = registry; this.routingTags = routingTags; var tags = MicrometerUtils.mapTimingTags(routingTags); - timerRoute = Timer.builder("raptor." + namePrefix + ".route").tags(tags).register(registry); + timerRoute = Timer.builder("raptor." + namePrefix + ".route") + .tags(tags) + .register(registry); routeTransitTimer = Timer.builder("raptor." + namePrefix + ".minute.transit") .tags(tags) .register(registry); diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/startonboardaccess/RoutingStartOnBoardAccess.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/startonboardaccess/RoutingStartOnBoardAccess.java index c87c6e2876b..04060969b55 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/startonboardaccess/RoutingStartOnBoardAccess.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/startonboardaccess/RoutingStartOnBoardAccess.java @@ -9,7 +9,8 @@ import org.opentripplanner.street.search.state.State; public final class RoutingStartOnBoardAccess - implements RaptorStartOnBoardAccess, RoutingAccessEgress { + implements RaptorStartOnBoardAccess, RoutingAccessEgress +{ private final int routeIndex; private final int tripScheduleIndex; diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java index f075b4b6017..fa9e6e9077a 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java @@ -67,7 +67,6 @@ public static List route( final StreetPathToLegsMapper streetPathToLegsMapper = new StreetPathToLegsMapper( new TransitServiceResolver(transitService), transitService.getTimeZone(), - graph.streetNotesService, streetDetailsService, graph.ellipsoidToGeoidDifference ); diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripPatternForDate.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripPatternForDate.java index e943b5f1133..13c0a374368 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripPatternForDate.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripPatternForDate.java @@ -175,7 +175,7 @@ public boolean equals(Object o) { } TripPatternForDate that = (TripPatternForDate) o; - return (tripPattern.equals(that.tripPattern) && serviceDate.equals(that.serviceDate)); + return tripPattern.equals(that.tripPattern) && serviceDate.equals(that.serviceDate); } @Override diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculator.java index 0921cfc4c64..8b43c2936f1 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculator.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculator.java @@ -11,8 +11,8 @@ *

* This class is immutable and thread safe. */ -public final class DefaultCostCalculator - implements RaptorCostCalculator { +public final class DefaultCostCalculator implements + RaptorCostCalculator { private final int boardCostOnly; private final int transferCostOnly; @@ -47,9 +47,10 @@ public DefaultCostCalculator( this.boardAndTransferCost = transferCostOnly + boardCostOnly; this.waitFactor = RaptorCostConverter.toRaptorCost(waitReluctanceFactor); - this.transitFactors = transitReluctanceFactors == null - ? new SingleValueFactorStrategy(GeneralizedCostParameters.DEFAULT_TRANSIT_RELUCTANCE) - : new IndexBasedFactorStrategy(transitReluctanceFactors); + this.transitFactors = + transitReluctanceFactors == null + ? new SingleValueFactorStrategy(GeneralizedCostParameters.DEFAULT_TRANSIT_RELUCTANCE) + : new IndexBasedFactorStrategy(transitReluctanceFactors); this.stopBoardAlightTransferCosts = stopBoardAlightTransferCosts; } diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/WheelchairCostCalculator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/WheelchairCostCalculator.java index 05715182e99..ad0d597929b 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/WheelchairCostCalculator.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/WheelchairCostCalculator.java @@ -6,8 +6,8 @@ import org.opentripplanner.raptor.spi.RaptorTransferConstraint; import org.opentripplanner.routing.api.request.preference.AccessibilityPreferences; -public class WheelchairCostCalculator - implements RaptorCostCalculator { +public class WheelchairCostCalculator implements + RaptorCostCalculator { private final RaptorCostCalculator delegate; private final int[] wheelchairBoardingCost; diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyAlightEvent.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyAlightEvent.java index 17dd5799f4d..b801c519619 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyAlightEvent.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyAlightEvent.java @@ -8,8 +8,7 @@ /** * Represents a result of a {@link TripFrequencyAlightSearch}, with materialized {@link TripTimes} */ -final class FrequencyAlightEvent - extends FrequencyBoardOrAlightEvent { +final class FrequencyAlightEvent extends FrequencyBoardOrAlightEvent { public FrequencyAlightEvent( TripPatternForDates raptorTripPattern, diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardOrAlightEvent.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardOrAlightEvent.java index 8650e7a5034..9473438c82d 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardOrAlightEvent.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardOrAlightEvent.java @@ -27,8 +27,9 @@ * save some resources. This kind of optimization is probably easier to do after a a clean up of the * internal OTP transit model. */ -abstract class FrequencyBoardOrAlightEvent - implements RaptorBoardOrAlightEvent, TripSchedule { +abstract class FrequencyBoardOrAlightEvent implements + RaptorBoardOrAlightEvent, + TripSchedule { protected final TripPatternForDates raptorTripPattern; protected final TripTimes tripTimes; diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardingEvent.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardingEvent.java index 130b7275b75..852d93108c8 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardingEvent.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardingEvent.java @@ -8,8 +8,7 @@ /** * Represents a result of a {@link TripFrequencyBoardSearch}, with materialized {@link TripTimes} */ -final class FrequencyBoardingEvent - extends FrequencyBoardOrAlightEvent { +final class FrequencyBoardingEvent extends FrequencyBoardOrAlightEvent { public FrequencyBoardingEvent( TripPatternForDates raptorTripPattern, diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyAlightSearch.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyAlightSearch.java index 9a841dbd05c..ecfdceab506 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyAlightSearch.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyAlightSearch.java @@ -12,8 +12,8 @@ * Searches for a concrete trip time for a frequency based pattern. The {@link FrequencyEntry}s are * scanned to find the earliest possible departure time. */ -public final class TripFrequencyAlightSearch - implements RaptorTripScheduleSearch { +public final class TripFrequencyAlightSearch implements + RaptorTripScheduleSearch { private final TripPatternForDates patternForDates; diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyBoardSearch.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyBoardSearch.java index b56d30381e1..6493f204b0c 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyBoardSearch.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyBoardSearch.java @@ -12,8 +12,8 @@ * Searches for a concrete trip time for a frequency based pattern. The {@link FrequencyEntry}s are * scanned to find the latest possible alighting time. */ -public final class TripFrequencyBoardSearch - implements RaptorTripScheduleSearch { +public final class TripFrequencyBoardSearch implements + RaptorTripScheduleSearch { private final TripPatternForDates patternForDates; diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorTransitDataMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorTransitDataMapper.java index 50c51c28bca..ddd20077e68 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorTransitDataMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorTransitDataMapper.java @@ -123,28 +123,26 @@ private HashMap> mapTripPatterns( List tripPatternForDates = Collections.synchronizedList(new ArrayList<>()); // THIS CODE RUNS IN PARALLEL - allServiceDates - .parallelStream() - .forEach(serviceDate -> { - // Create a List to hold the values for this iteration. The results are then added - // to the common synchronized list at the end. - List values = new ArrayList<>(); - - // This nested loop could be quite inefficient. - // Maybe determine in advance which patterns are running on each service and day. - for (TripPattern oldTripPattern : allTripPatterns) { - TripPatternForDate tripPatternForDate = tripPatternForDateMapper.map( - oldTripPattern.getScheduledTimetable(), - serviceDate - ); - if (tripPatternForDate != null) { - values.add(tripPatternForDate); - } + allServiceDates.parallelStream().forEach(serviceDate -> { + // Create a List to hold the values for this iteration. The results are then added + // to the common synchronized list at the end. + List values = new ArrayList<>(); + + // This nested loop could be quite inefficient. + // Maybe determine in advance which patterns are running on each service and day. + for (TripPattern oldTripPattern : allTripPatterns) { + TripPatternForDate tripPatternForDate = tripPatternForDateMapper.map( + oldTripPattern.getScheduledTimetable(), + serviceDate + ); + if (tripPatternForDate != null) { + values.add(tripPatternForDate); } - if (!values.isEmpty()) { - tripPatternForDates.addAll(values); - } - }); + } + if (!values.isEmpty()) { + tripPatternForDates.addAll(values); + } + }); // END PARALLEL CODE return keyByRunningPeriodDates(tripPatternForDates); diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripPatternForDates.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripPatternForDates.java index 24628a4804b..423cf6fe0ec 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripPatternForDates.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripPatternForDates.java @@ -27,7 +27,8 @@ public class TripPatternForDates RaptorRoute, RaptorTimeTable, RaptorTripPattern, - TripSearchTimetable { + TripSearchTimetable +{ private static final int FIRST_STOP_POS_IN_PATTERN = 0; diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearch.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearch.java index abfbf53e89a..a13b7c28cd8 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearch.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearch.java @@ -22,8 +22,9 @@ * * @param The TripSchedule type defined by the user of the raptor API. */ -public final class TripScheduleAlightSearch - implements RaptorTripScheduleSearch, RaptorBoardOrAlightEvent { +public final class TripScheduleAlightSearch implements + RaptorTripScheduleSearch, + RaptorBoardOrAlightEvent { private final TripSearchTimetable timetable; private final int nTrips; diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearch.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearch.java index 47f64782021..5ed149c6ce8 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearch.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearch.java @@ -20,8 +20,9 @@ * * @param The TripSchedule type defined by the user of the raptor API. */ -public final class TripScheduleBoardSearch - implements RaptorTripScheduleSearch, RaptorBoardOrAlightEvent { +public final class TripScheduleBoardSearch implements + RaptorTripScheduleSearch, + RaptorBoardOrAlightEvent { private final TripSearchTimetable timetable; private final int nTrips; diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripTimesForDaysIndex.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripTimesForDaysIndex.java index 902ae7296d3..0de778ebb6f 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripTimesForDaysIndex.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripTimesForDaysIndex.java @@ -52,8 +52,7 @@ static TripTimesForDaysIndex ofTripTimesForDay(List departureTimes, int[] this.tripIndex = new int[list .stream() .mapToInt(a -> a.length) - .sum() * - 2]; + .sum() * 2]; int[] a; // 'day' is the current day index @@ -150,7 +149,11 @@ public String toString() { } var buf = new StringBuilder(); for (int i = 0; i < tripIndex.length; i += 2) { - buf.append(tripIndex[i]).append(':').append(tripIndex[i + 1]).append(' '); + buf + .append(tripIndex[i]) + .append(':') + .append(tripIndex[i + 1]) + .append(' '); } return buf.substring(0, buf.length() - 1); } diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPath.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPath.java index 88d7b1d1f6f..701a3934784 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPath.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPath.java @@ -19,7 +19,8 @@ */ public class OptimizedPath extends Path - implements TransferOptimized { + implements TransferOptimized +{ private final int transferPriorityCost; private final int waitTimeOptimizedCost; diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/configure/TransferOptimizationServiceConfigurator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/configure/TransferOptimizationServiceConfigurator.java index 7e264254258..55a5c1930e3 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/configure/TransferOptimizationServiceConfigurator.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/configure/TransferOptimizationServiceConfigurator.java @@ -58,9 +58,7 @@ private TransferOptimizationServiceConfigurator( /** * Scope: Request */ - public static OptimizeTransferService< - T - > createOptimizeTransferService( + public static OptimizeTransferService createOptimizeTransferService( IntFunction stopLookup, RaptorStopNameResolver stopNameResolver, ConstrainedTransferService transferService, @@ -129,9 +127,10 @@ private MinSafeTransferTimeCalculator createMinSafeTxTimeService() { } private TransferGenerator createTransferGenerator(boolean transferPriority) { - var transferServiceAdaptor = (transferService != null && transferPriority) - ? TransferServiceAdaptor.create(stopLookup, transferService) - : TransferServiceAdaptor.noop(); + var transferServiceAdaptor = + transferService != null && transferPriority + ? TransferServiceAdaptor.create(stopLookup, transferService) + : TransferServiceAdaptor.noop(); return new TransferGenerator<>(transferServiceAdaptor, transitDataProvider); } diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTail.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTail.java index ea22497668a..bd3cbe67c7c 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTail.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTail.java @@ -28,7 +28,8 @@ */ public class OptimizedPathTail extends PathBuilder - implements TransferOptimized { + implements TransferOptimized +{ @Nullable private final TransferWaitTimeCostCalculator waitTimeCostCalculator; @@ -51,13 +52,13 @@ public OptimizedPathTail( ) { super(slackProvider, iterationDepartureTime, costCalculator, stopNameResolver, null); this.waitTimeCostCalculator = waitTimeCostCalculator; - this.stopPriorityCostCalculator = (stopBoardAlightTransferCosts != null && - extraStopBoardAlightCostsFactor > 0.01) - ? new StopPriorityCostCalculator( - extraStopBoardAlightCostsFactor, - stopBoardAlightTransferCosts - ) - : null; + this.stopPriorityCostCalculator = + stopBoardAlightTransferCosts != null && extraStopBoardAlightCostsFactor > 0.01 + ? new StopPriorityCostCalculator( + extraStopBoardAlightCostsFactor, + stopBoardAlightTransferCosts + ) + : null; } private OptimizedPathTail(OptimizedPathTail other) { diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainService.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainService.java index 94dcb7d0889..4e2f38e9595 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainService.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainService.java @@ -162,9 +162,12 @@ private Set> findBestTransferOption( // prune the transfers AFTER the transit-leg. The transfers are sorted on // arrival-time in descending order, so the earliest-arrival-time is the // last element of the list of transfers. - int earliestDepartureTimeFromLeg = i == 0 - ? accessArrivalTime - : last(possibleTransfers.get(i - 1)).to().time(); + int earliestDepartureTimeFromLeg = + i == 0 + ? accessArrivalTime + : last(possibleTransfers.get(i - 1)) + .to() + .time(); // create a tailSelector for the tails produced in the last round and use it to filter them // based on the transfer-arrival-time and given filter diff --git a/application/src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegs.java b/application/src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegs.java index 83c48b836ad..724f186f5de 100644 --- a/application/src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegs.java +++ b/application/src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegs.java @@ -84,13 +84,11 @@ public static List getAlternativeLegs( Station fromStation = fromStop.getParentStation(); Station toStation = toStop.getParentStation(); - Collection origins = fromStation == null || exactOriginStop - ? List.of(fromStop) - : fromStation.getChildStops(); + Collection origins = + fromStation == null || exactOriginStop ? List.of(fromStop) : fromStation.getChildStops(); - Collection destinations = toStation == null || exactDestinationStop - ? List.of(toStop) - : toStation.getChildStops(); + Collection destinations = + toStation == null || exactDestinationStop ? List.of(toStop) : toStation.getChildStops(); Comparator legComparator = Comparator.comparing( ScheduledTransitLeg::startTime @@ -168,9 +166,10 @@ private static Stream generateLegs( continue; } - boolean departureTimeInRange = direction == NavigationDirection.PREVIOUS - ? tripTimes.getDepartureTime(boardingPosition) <= secondsSinceMidnight - : tripTimes.getDepartureTime(boardingPosition) >= secondsSinceMidnight; + boolean departureTimeInRange = + direction == NavigationDirection.PREVIOUS + ? tripTimes.getDepartureTime(boardingPosition) <= secondsSinceMidnight + : tripTimes.getDepartureTime(boardingPosition) >= secondsSinceMidnight; if (departureTimeInRange) { pq.add( diff --git a/application/src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegsFilter.java b/application/src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegsFilter.java index e3b214d9c86..d8deab38bce 100644 --- a/application/src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegsFilter.java +++ b/application/src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegsFilter.java @@ -8,17 +8,16 @@ public enum AlternativeLegsFilter { NO_FILTER((Leg leg) -> (TripPattern tripPattern) -> true), SAME_AGENCY( - (Leg leg) -> - (TripPattern tripPattern) -> leg.agency().equals(tripPattern.getRoute().getAgency()) + (Leg leg) -> (TripPattern tripPattern) -> + leg.agency().equals(tripPattern.getRoute().getAgency()) ), SAME_ROUTE((Leg leg) -> (TripPattern tripPattern) -> leg.route().equals(tripPattern.getRoute())), SAME_MODE( (Leg leg) -> (TripPattern tripPattern) -> leg.trip().getMode().equals(tripPattern.getMode()) ), SAME_SUBMODE( - (Leg leg) -> - (TripPattern tripPattern) -> - leg.trip().getNetexSubMode().equals(tripPattern.getNetexSubmode()) + (Leg leg) -> (TripPattern tripPattern) -> + leg.trip().getNetexSubMode().equals(tripPattern.getNetexSubmode()) ); public final Function> predicateGenerator; diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/RequestModes.java b/application/src/main/java/org/opentripplanner/routing/api/request/RequestModes.java index f2eef44c6bf..a811684ba84 100644 --- a/application/src/main/java/org/opentripplanner/routing/api/request/RequestModes.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/RequestModes.java @@ -32,12 +32,11 @@ private RequestModes( StreetMode directMode, StreetMode transferMode ) { - this.accessMode = (accessMode != null && accessMode.accessAllowed()) ? accessMode : NOT_SET; - this.egressMode = (egressMode != null && egressMode.egressAllowed()) ? egressMode : NOT_SET; + this.accessMode = accessMode != null && accessMode.accessAllowed() ? accessMode : NOT_SET; + this.egressMode = egressMode != null && egressMode.egressAllowed() ? egressMode : NOT_SET; this.directMode = directMode != null ? directMode : NOT_SET; - this.transferMode = (transferMode != null && transferMode.transferAllowed()) - ? transferMode - : NOT_SET; + this.transferMode = + transferMode != null && transferMode.transferAllowed() ? transferMode : NOT_SET; } public RequestModes(RequestModesBuilder builder) { diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/RouteRequest.java b/application/src/main/java/org/opentripplanner/routing/api/request/RouteRequest.java index 2f145aea30f..9349c72674c 100644 --- a/application/src/main/java/org/opentripplanner/routing/api/request/RouteRequest.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/RouteRequest.java @@ -99,9 +99,10 @@ private RouteRequest() { // The given dateTime will be set to a whole number of seconds. We don't do sub-second // accuracy, and if we set the millisecond part to a non-zero value, rounding will not be // guaranteed to be the same for departAt and arriveBy queries. - this.dateTime = (!builder.defaultRequest && builder.dateTime == null) - ? normalizeNow() - : TimeUtils.truncateToSeconds(builder.dateTime); + this.dateTime = + !builder.defaultRequest && builder.dateTime == null + ? normalizeNow() + : TimeUtils.truncateToSeconds(builder.dateTime); this.arriveBy = builder.arriveBy; this.timetableView = builder.timetableView; diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/TripOnDateReference.java b/application/src/main/java/org/opentripplanner/routing/api/request/TripOnDateReference.java index 2ad02762d87..ad2255a8fce 100644 --- a/application/src/main/java/org/opentripplanner/routing/api/request/TripOnDateReference.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/TripOnDateReference.java @@ -4,7 +4,8 @@ import org.opentripplanner.core.model.id.FeedScopedId; public sealed interface TripOnDateReference - permits TripOnDateReferenceWithTripOnServiceDateId, TripOnDateReferenceWithTripAndDate { + permits TripOnDateReferenceWithTripOnServiceDateId, TripOnDateReferenceWithTripAndDate +{ static TripOnDateReference ofTripIdAndServiceDate(FeedScopedId tripId, LocalDate serviceDate) { return new TripOnDateReferenceWithTripAndDate(tripId, serviceDate); } diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/TripOnDateReferenceWithTripAndDate.java b/application/src/main/java/org/opentripplanner/routing/api/request/TripOnDateReferenceWithTripAndDate.java index 52cc68d1391..9fc504d2afc 100644 --- a/application/src/main/java/org/opentripplanner/routing/api/request/TripOnDateReferenceWithTripAndDate.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/TripOnDateReferenceWithTripAndDate.java @@ -10,5 +10,7 @@ * @param id The id of the trip * @param serviceDate The service date of the trip */ -public record TripOnDateReferenceWithTripAndDate(FeedScopedId id, LocalDate serviceDate) implements - TripOnDateReference {} +public record TripOnDateReferenceWithTripAndDate( + FeedScopedId id, + LocalDate serviceDate +) implements TripOnDateReference {} diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/TripOnDateReferenceWithTripOnServiceDateId.java b/application/src/main/java/org/opentripplanner/routing/api/request/TripOnDateReferenceWithTripOnServiceDateId.java index e4c0d6a6024..351eb20c7a1 100644 --- a/application/src/main/java/org/opentripplanner/routing/api/request/TripOnDateReferenceWithTripOnServiceDateId.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/TripOnDateReferenceWithTripOnServiceDateId.java @@ -7,5 +7,6 @@ * * @param id The id of the trip on service date */ -public record TripOnDateReferenceWithTripOnServiceDateId(FeedScopedId id) implements - TripOnDateReference {} +public record TripOnDateReferenceWithTripOnServiceDateId( + FeedScopedId id +) implements TripOnDateReference {} diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/framework/AbstractLinearFunction.java b/application/src/main/java/org/opentripplanner/routing/api/request/framework/AbstractLinearFunction.java index 37f9c8fe14a..8e49126f196 100644 --- a/application/src/main/java/org/opentripplanner/routing/api/request/framework/AbstractLinearFunction.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/framework/AbstractLinearFunction.java @@ -15,7 +15,8 @@ */ abstract sealed class AbstractLinearFunction implements Serializable - permits CostLinearFunction, TimePenalty { + permits CostLinearFunction, TimePenalty +{ private final T constant; diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/preference/EscalatorPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/EscalatorPreferences.java index 5744376ee6b..f8c266ca1ed 100644 --- a/application/src/main/java/org/opentripplanner/routing/api/request/preference/EscalatorPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/EscalatorPreferences.java @@ -54,7 +54,7 @@ public boolean equals(Object o) { return false; } EscalatorPreferences that = (EscalatorPreferences) o; - return (doubleEquals(that.reluctance, reluctance) && doubleEquals(that.speed, speed)); + return doubleEquals(that.reluctance, reluctance) && doubleEquals(that.speed, speed); } @Override diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterDebugProfile.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterDebugProfile.java index a453048aac4..53d15dfe32d 100644 --- a/application/src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterDebugProfile.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterDebugProfile.java @@ -43,11 +43,9 @@ public static ItineraryFilterDebugProfile ofDebugEnabled(boolean enabled) { @Override public String typeDescription() { - return ( - """ - Enable this to attach a system notice to itineraries instead of removing them. This is very - convenient when tuning the itinerary-filter-chain.""" - ); + return """ + Enable this to attach a system notice to itineraries instead of removing them. This is very + convenient when tuning the itinerary-filter-chain."""; } @Override diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterPreferences.java index 0b2b2fb1642..0fdf1ccc200 100644 --- a/application/src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterPreferences.java @@ -211,8 +211,7 @@ public boolean equals(Object o) { Double.compare( that.groupedOtherThanSameLegsMaxCostMultiplier, groupedOtherThanSameLegsMaxCostMultiplier - ) == - 0 && + ) == 0 && Double.compare(that.groupSimilarityKeepOne, groupSimilarityKeepOne) == 0 && Double.compare(that.groupSimilarityKeepThree, groupSimilarityKeepThree) == 0 && Double.compare(that.minBikeParkingDistance, minBikeParkingDistance) == 0 && diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/preference/MaxStopCountLimit.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/MaxStopCountLimit.java index 66e496cfbcb..fa9919eab22 100644 --- a/application/src/main/java/org/opentripplanner/routing/api/request/preference/MaxStopCountLimit.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/MaxStopCountLimit.java @@ -70,7 +70,7 @@ public boolean equals(Object o) { var that = (MaxStopCountLimit) o; - return (defaultLimit == that.defaultLimit && limitsForModes.equals(that.limitsForModes)); + return defaultLimit == that.defaultLimit && limitsForModes.equals(that.limitsForModes); } @Override diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/preference/TransferOptimizationPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/TransferOptimizationPreferences.java index 2a0cc11bad6..86105945875 100644 --- a/application/src/main/java/org/opentripplanner/routing/api/request/preference/TransferOptimizationPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/TransferOptimizationPreferences.java @@ -15,7 +15,8 @@ * THIS CLASS IS IMMUTABLE AND THREAD-SAFE. */ public final class TransferOptimizationPreferences - implements Serializable, TransferOptimizationParameters { + implements Serializable, TransferOptimizationParameters +{ private final boolean optimizeTransferWaitTime; private final double minSafeWaitTimeFactor; diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/preference/WheelchairPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/WheelchairPreferences.java index 7c82ac3803a..cc971f08564 100644 --- a/application/src/main/java/org/opentripplanner/routing/api/request/preference/WheelchairPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/WheelchairPreferences.java @@ -243,7 +243,8 @@ public Builder withElevator(AccessibilityPreferences elevator) { } public Builder withElevator(Consumer body) { - this.elevator = this.elevator.copyOfWithDefaultCosts(DEFAULT_ELEVATOR_PREFERENCES) + this.elevator = this.elevator + .copyOfWithDefaultCosts(DEFAULT_ELEVATOR_PREFERENCES) .apply(body) .build(); return this; diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/preference/filter/VehicleParkingFilter.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/filter/VehicleParkingFilter.java index 6ffe0a415de..c99d9fa5758 100644 --- a/application/src/main/java/org/opentripplanner/routing/api/request/preference/filter/VehicleParkingFilter.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/filter/VehicleParkingFilter.java @@ -77,7 +77,7 @@ public boolean equals(Object o) { return false; } VehicleParkingFilter that = (VehicleParkingFilter) o; - return (Arrays.equals(not, that.not) && Arrays.equals(select, that.select)); + return Arrays.equals(not, that.not) && Arrays.equals(select, that.select); } @Override diff --git a/application/src/main/java/org/opentripplanner/routing/api/response/TripSearchMetadata.java b/application/src/main/java/org/opentripplanner/routing/api/response/TripSearchMetadata.java index 94a6ba39801..3d472e4232d 100644 --- a/application/src/main/java/org/opentripplanner/routing/api/response/TripSearchMetadata.java +++ b/application/src/main/java/org/opentripplanner/routing/api/response/TripSearchMetadata.java @@ -39,9 +39,10 @@ public static TripSearchMetadata createForArriveBy( @Nullable Instant firstDepartureTime ) { // Round down to the minute before to avoid duplicates. This may cause missed itineraries. - Instant actualEdt = firstDepartureTime == null - ? earliestDepartureTimeUsed - : firstDepartureTime.minusSeconds(60).truncatedTo(ChronoUnit.MINUTES); + Instant actualEdt = + firstDepartureTime == null + ? earliestDepartureTimeUsed + : firstDepartureTime.minusSeconds(60).truncatedTo(ChronoUnit.MINUTES); return new TripSearchMetadata( pageDepartureTimeStart, @@ -61,9 +62,10 @@ public static TripSearchMetadata createForDepartAfter( ) { // There is no way to make this work properly with lastDepartureTime. If we round down we get // duplicates, if we round up we might skip itineraries. - Instant nextDateTime = lastDepartureTime == null - ? requestDepartureTime.plus(raptorSearchWindowUsed) - : lastDepartureTime.plusSeconds(60).truncatedTo(ChronoUnit.MINUTES); + Instant nextDateTime = + lastDepartureTime == null + ? requestDepartureTime.plus(raptorSearchWindowUsed) + : lastDepartureTime.plusSeconds(60).truncatedTo(ChronoUnit.MINUTES); return new TripSearchMetadata( pageDepartureTimeStart, diff --git a/application/src/main/java/org/opentripplanner/routing/graph/SerializedGraphObject.java b/application/src/main/java/org/opentripplanner/routing/graph/SerializedGraphObject.java index 9b7641c3f82..e9f1c6e33f4 100644 --- a/application/src/main/java/org/opentripplanner/routing/graph/SerializedGraphObject.java +++ b/application/src/main/java/org/opentripplanner/routing/graph/SerializedGraphObject.java @@ -41,6 +41,7 @@ import org.opentripplanner.transit.model.basic.SubMode; import org.opentripplanner.transit.model.network.RoutingTripPattern; import org.opentripplanner.transit.service.TransitRepository; +import org.opentripplanner.utils.collection.ListUtils; import org.opentripplanner.utils.lang.OtpNumberFormat; import org.opentripplanner.utils.logging.ProgressTracker; import org.slf4j.Logger; @@ -114,7 +115,7 @@ public SerializedGraphObject( FareServiceFactory fareServiceFactory ) { this.graph = graph; - this.edges = graph.getEdges(); + this.edges = ListUtils.ofIterable(graph.listEdges()); this.osmInfoGraphBuildRepository = osmInfoGraphBuildRepository; this.streetDetailsRepository = streetDetailsRepository; this.streetRepository = streetRepository; diff --git a/application/src/main/java/org/opentripplanner/routing/linking/LinkingContextFactory.java b/application/src/main/java/org/opentripplanner/routing/linking/LinkingContextFactory.java index aa75cd23e27..5cdecc02330 100644 --- a/application/src/main/java/org/opentripplanner/routing/linking/LinkingContextFactory.java +++ b/application/src/main/java/org/opentripplanner/routing/linking/LinkingContextFactory.java @@ -139,9 +139,10 @@ private Set getFromVertices( if (from == null) { return Set.of(); } - var modes = request.accessMode() != StreetMode.NOT_SET - ? EnumSet.of(request.accessMode()) - : EnumSet.noneOf(StreetMode.class); + var modes = + request.accessMode() != StreetMode.NOT_SET + ? EnumSet.of(request.accessMode()) + : EnumSet.noneOf(StreetMode.class); if (request.directMode() != StreetMode.NOT_SET) { modes.add(request.directMode()); } @@ -156,9 +157,10 @@ private Set getToVertices( if (to == null) { return Set.of(); } - var modes = request.egressMode() != StreetMode.NOT_SET - ? EnumSet.of(request.egressMode()) - : EnumSet.noneOf(StreetMode.class); + var modes = + request.egressMode() != StreetMode.NOT_SET + ? EnumSet.of(request.egressMode()) + : EnumSet.noneOf(StreetMode.class); if (request.directMode() != StreetMode.NOT_SET) { modes.add(request.directMode()); } diff --git a/application/src/main/java/org/opentripplanner/routing/linking/internal/VertexCreationService.java b/application/src/main/java/org/opentripplanner/routing/linking/internal/VertexCreationService.java index ffb3c66cc3c..08216800d9f 100644 --- a/application/src/main/java/org/opentripplanner/routing/linking/internal/VertexCreationService.java +++ b/application/src/main/java/org/opentripplanner/routing/linking/internal/VertexCreationService.java @@ -53,9 +53,10 @@ public Vertex createVertexFromCoordinate( ) { LOG.debug("Creating {} vertex for {}", type.description(), coordinate); - I18NString name = label == null || label.isEmpty() - ? new LocalizedString(type.translationKey()) - : new NonLocalizedString(label); + I18NString name = + label == null || label.isEmpty() + ? new LocalizedString(type.translationKey()) + : new NonLocalizedString(label); var temporaryStreetLocation = new TemporaryStreetLocation(coordinate, name); diff --git a/application/src/main/java/org/opentripplanner/routing/refetch/RefetchItineraryService.java b/application/src/main/java/org/opentripplanner/routing/refetch/RefetchItineraryService.java index 19aea85789f..5e0d4379b83 100644 --- a/application/src/main/java/org/opentripplanner/routing/refetch/RefetchItineraryService.java +++ b/application/src/main/java/org/opentripplanner/routing/refetch/RefetchItineraryService.java @@ -25,7 +25,6 @@ import org.opentripplanner.routing.linking.internal.VertexCreationService; import org.opentripplanner.routing.services.TransitAlertService; import org.opentripplanner.service.streetdetails.StreetDetailsService; -import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.street.graph.Graph; import org.opentripplanner.street.linking.TemporaryVerticesContainer; import org.opentripplanner.street.model.StreetMode; @@ -59,18 +58,6 @@ public class RefetchItineraryService { private final StreetPathToLegsMapper streetPathToLegsMapper; private final StreetLimitationParametersService streetLimitationParametersService; - public RefetchItineraryService(OtpServerRequestContext serverContext) { - this( - serverContext.graph(), - serverContext.transitService(), - serverContext.transitAlertService(), - serverContext.transferService(), - serverContext.streetDetailsService(), - serverContext.linkingContextFactory(), - serverContext.streetLimitationParametersService() - ); - } - public RefetchItineraryService( Graph graph, TransitService transitService, @@ -88,7 +75,6 @@ public RefetchItineraryService( this.streetPathToLegsMapper = new StreetPathToLegsMapper( new TransitServiceResolver(transitService), transitService.getTimeZone(), - graph.streetNotesService, streetDetailsService, graph.ellipsoidToGeoidDifference ); diff --git a/application/src/main/java/org/opentripplanner/routing/services/TransitAlertService.java b/application/src/main/java/org/opentripplanner/routing/services/TransitAlertService.java index 0255886ea8f..eb361cab4d5 100644 --- a/application/src/main/java/org/opentripplanner/routing/services/TransitAlertService.java +++ b/application/src/main/java/org/opentripplanner/routing/services/TransitAlertService.java @@ -7,6 +7,8 @@ import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.routing.alertpatch.StopCondition; import org.opentripplanner.routing.alertpatch.TransitAlert; +import org.opentripplanner.transit.api.request.TransitAlertRequest; +import org.opentripplanner.transit.model.filter.transit.TransitAlertMatcherFactory; import org.opentripplanner.transit.model.timetable.Direction; /** @@ -32,6 +34,18 @@ public interface TransitAlertService { Collection getAllAlerts(); + /** + * Returns all alerts matching the given request. A request without filters matches all alerts. + */ + default Collection findAlerts(TransitAlertRequest request) { + var alerts = getAllAlerts(); + if (request.filters().isEmpty()) { + return alerts; + } + var matcher = TransitAlertMatcherFactory.of(request); + return alerts.stream().filter(matcher::match).toList(); + } + TransitAlert getAlertById(FeedScopedId id); default Collection getStopAlerts(FeedScopedId stop) { diff --git a/application/src/main/java/org/opentripplanner/routing/util/DiffEntry.java b/application/src/main/java/org/opentripplanner/routing/util/DiffEntry.java index d3be54bb80f..a3033349c37 100644 --- a/application/src/main/java/org/opentripplanner/routing/util/DiffEntry.java +++ b/application/src/main/java/org/opentripplanner/routing/util/DiffEntry.java @@ -29,7 +29,7 @@ public boolean isEqual() { * exist left only - or, exist right only */ public String status(String equal, String left, String right) { - return leftOnly() ? left : (rightOnly() ? right : equal); + return leftOnly() ? left : rightOnly() ? right : equal; } @Override diff --git a/application/src/main/java/org/opentripplanner/service/osminfo/internal/DefaultOsmInfoGraphBuildRepository.java b/application/src/main/java/org/opentripplanner/service/osminfo/internal/DefaultOsmInfoGraphBuildRepository.java index 6e2613f9fe3..872bf22d53a 100644 --- a/application/src/main/java/org/opentripplanner/service/osminfo/internal/DefaultOsmInfoGraphBuildRepository.java +++ b/application/src/main/java/org/opentripplanner/service/osminfo/internal/DefaultOsmInfoGraphBuildRepository.java @@ -17,7 +17,8 @@ import org.opentripplanner.utils.tostring.ToStringBuilder; public class DefaultOsmInfoGraphBuildRepository - implements OsmInfoGraphBuildRepository, Serializable { + implements OsmInfoGraphBuildRepository, Serializable +{ private final Map platforms = new HashMap<>(); private final Map areaPlatforms = new HashMap<>(); diff --git a/application/src/main/java/org/opentripplanner/service/realtimevehicles/internal/RealtimeVehicleRepositoryLifecycle.java b/application/src/main/java/org/opentripplanner/service/realtimevehicles/internal/RealtimeVehicleRepositoryLifecycle.java index 4e3f1e428cb..8f35f548ee5 100644 --- a/application/src/main/java/org/opentripplanner/service/realtimevehicles/internal/RealtimeVehicleRepositoryLifecycle.java +++ b/application/src/main/java/org/opentripplanner/service/realtimevehicles/internal/RealtimeVehicleRepositoryLifecycle.java @@ -11,7 +11,8 @@ * that is never frozen are simply discarded — this supports transaction rollback in the future. */ public class RealtimeVehicleRepositoryLifecycle - implements RepositoryLifecycle { + implements RepositoryLifecycle +{ @Override public RealtimeVehicleRepository copyOnWrite(RealtimeVehicleRepositorySnapshot snapshot) { diff --git a/application/src/main/java/org/opentripplanner/service/streetdetails/model/InclinedEdgeLevelInfo.java b/application/src/main/java/org/opentripplanner/service/streetdetails/model/InclinedEdgeLevelInfo.java index 9637a2d9ee5..48bd7b1af04 100644 --- a/application/src/main/java/org/opentripplanner/service/streetdetails/model/InclinedEdgeLevelInfo.java +++ b/application/src/main/java/org/opentripplanner/service/streetdetails/model/InclinedEdgeLevelInfo.java @@ -30,7 +30,7 @@ public boolean canBeAppliedToEdge(Edge edge) { edge.getToVertex() instanceof OsmVertex toVertex && edge.getFromVertex() instanceof OsmVertex fromVertex && ((lowerVertexInfo.osmNodeId() == fromVertex.nodeId() && - upperVertexInfo.osmNodeId() == toVertex.nodeId()) || + upperVertexInfo.osmNodeId() == toVertex.nodeId()) || (lowerVertexInfo.osmNodeId() == toVertex.nodeId() && upperVertexInfo.osmNodeId() == fromVertex.nodeId())) ); diff --git a/application/src/main/java/org/opentripplanner/service/worldenvelope/model/MedianCalcForDoubles.java b/application/src/main/java/org/opentripplanner/service/worldenvelope/model/MedianCalcForDoubles.java index 3eeb52ce0e2..c2cc2ba894f 100644 --- a/application/src/main/java/org/opentripplanner/service/worldenvelope/model/MedianCalcForDoubles.java +++ b/application/src/main/java/org/opentripplanner/service/worldenvelope/model/MedianCalcForDoubles.java @@ -39,7 +39,7 @@ public double median() { if (n % 2 == 1) { return array[(n - 1) / 2]; } else { - int i = (n / 2) - 1; + int i = n / 2 - 1; return (array[i] + array[i + 1]) / 2.0; } } diff --git a/application/src/main/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelope.java b/application/src/main/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelope.java index e82e5a9a082..1497e900364 100644 --- a/application/src/main/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelope.java +++ b/application/src/main/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelope.java @@ -99,9 +99,10 @@ private static WgsCoordinate calculateMeanCenter( double centerLatitude = llLatitude + (urLatitude - llLatitude) / 2.0; // Split normally at 180 degrees - double centerLongitude = (llLongitude < urLongitude) - ? llLongitude + (urLongitude - llLongitude) / 2.0 - : llLongitude + (360 - llLongitude + urLongitude) / 2.0; + double centerLongitude = + llLongitude < urLongitude + ? llLongitude + (urLongitude - llLongitude) / 2.0 + : llLongitude + (360 - llLongitude + urLongitude) / 2.0; return new WgsCoordinate(centerLatitude, centerLongitude); } diff --git a/application/src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java b/application/src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java deleted file mode 100644 index 9da568a4cab..00000000000 --- a/application/src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java +++ /dev/null @@ -1,219 +0,0 @@ -package org.opentripplanner.standalone.api; - -import graphql.schema.GraphQLSchema; -import io.micrometer.core.instrument.MeterRegistry; -import java.util.ArrayList; -import java.util.List; -import javax.annotation.Nullable; -import org.opentripplanner.apis.gtfs.GtfsApiParameters; -import org.opentripplanner.apis.transmodel.TransmodelAPIParameters; -import org.opentripplanner.ext.carpooling.CarpoolingService; -import org.opentripplanner.ext.dataoverlay.configuration.DataOverlayParameterBindings; -import org.opentripplanner.ext.dataoverlay.routing.DataOverlayContext; -import org.opentripplanner.ext.empiricaldelay.EmpiricalDelayService; -import org.opentripplanner.ext.flex.FlexParameters; -import org.opentripplanner.ext.geocoder.LuceneIndex; -import org.opentripplanner.ext.ojp.parameters.OjpApiParameters; -import org.opentripplanner.ext.ojp.parameters.TriasApiParameters; -import org.opentripplanner.ext.ridehailing.RideHailingService; -import org.opentripplanner.ext.sorlandsbanen.SorlandsbanenNorwayService; -import org.opentripplanner.ext.stopconsolidation.StopConsolidationService; -import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.framework.transaction.api.TransactionScope; -import org.opentripplanner.place.NearbyPlaceFinder; -import org.opentripplanner.place.NearbyStopFinder; -import org.opentripplanner.place.nearbystopfinder.StraightLineNearbyStopFinder; -import org.opentripplanner.place.nearbystopfinder.StreetNearbyStopFinder; -import org.opentripplanner.place.placefinder.StreetNearbyPlaceFinder; -import org.opentripplanner.raptor.api.request.RaptorTuningParameters; -import org.opentripplanner.raptor.configure.RaptorConfig; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitTuningParameters; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripSchedule; -import org.opentripplanner.routing.api.RoutingService; -import org.opentripplanner.routing.api.request.RouteRequest; -import org.opentripplanner.routing.fares.FareService; -import org.opentripplanner.routing.linking.LinkingContextFactory; -import org.opentripplanner.routing.services.TransitAlertService; -import org.opentripplanner.routing.via.ViaCoordinateTransferFactory; -import org.opentripplanner.service.realtimevehicles.RealtimeVehicleService; -import org.opentripplanner.service.streetdetails.StreetDetailsService; -import org.opentripplanner.service.vehicleparking.VehicleParkingService; -import org.opentripplanner.service.vehiclerental.VehicleRentalService; -import org.opentripplanner.service.worldenvelope.WorldEnvelopeService; -import org.opentripplanner.standalone.config.DebugUiConfig; -import org.opentripplanner.standalone.config.routerconfig.VectorTileConfig; -import org.opentripplanner.street.graph.Graph; -import org.opentripplanner.street.linking.VertexLinker; -import org.opentripplanner.street.model.edge.ExtensionRequestContext; -import org.opentripplanner.street.service.StreetLimitationParametersService; -import org.opentripplanner.transfer.regular.RegularTransferService; -import org.opentripplanner.transit.service.TransitService; - -/** - * The purpose of this class is to give APIs (HTTP Resources) read-only access to the OTP internal - * transit model. It allows individual API requests to use a limited number of methods and data - * structures without direct access to the internals of the server components. - * - * By using an interface, and not injecting each service class we avoid giving the resources access - * to the server implementation. The context is injected by Jersey. Instead of injecting this - * context interface, it is conceivable to inject each of the individual items within this context. - * - * But there is not a "real" need for this. For example, we do not have unit tests on the - * Resources. If we in the future would decide to write unit tests for the APIs, then we could - * eliminate this interface and just inject the components. See the bind method in OTPServer. - *

- * The OTP Server and the implementation of this class is responsible to make the necessary - * instances for request scoped objects. Hence; the user of this can assume that: - *

    - *
  1. Calling the methods of this interface will return the same object every time.
  2. - *
  3. - * If the returned component is mutable, then it will be a unique copy for each HTTP request. - *
  4. - *
- *

- * This class is not THREAD-SAFE, each HTTP request gets its own copy, but if there are multiple - * threads which accesses this context within the HTTP Request, then the caller is responsible - * for the synchronization. Only request scoped components need to be synchronized - they are - * potentially lazy initialized. - */ -@HttpRequestScoped -public interface OtpServerRequestContext { - DebugUiConfig debugUiConfig(); - - /** - * The transaction scope that was captured at the start of this HTTP request. It holds a strong - * reference to the current {@link org.opentripplanner.framework.transaction.internal.Transaction}, - * preventing the {@link org.opentripplanner.framework.transaction.internal.RepositorySnapshotCache} - * from GC-ing any snapshot used during this request. - */ - TransactionScope transactionScope(); - - /** - * A RouteRequest containing default parameters that will be cloned when handling each request. - */ - @HttpRequestScoped - RouteRequest defaultRouteRequest(); - - RaptorConfig raptorConfig(); - - Graph graph(); - - @HttpRequestScoped - TransitService transitService(); - - /** - * The application-wide alert service. Unlike {@link #transitService()} this is a long-lived - * singleton and is not tied to the transit snapshot of the request. - */ - TransitAlertService transitAlertService(); - - /** - * Get a request-scoped {@link RoutingService} valid for one HTTP request. It guarantees that - * the data and services used are consistent and operate on the same transit snapshot. Any - * realtime update that happens during the request will not affect the returned service and will - * not be visible to the request. - */ - @HttpRequestScoped - RoutingService routingService(); - - @HttpRequestScoped - RegularTransferService transferService(); - - /** - * Get information on geographical bounding box and center coordinates. - */ - WorldEnvelopeService worldEnvelopeService(); - - @HttpRequestScoped - RealtimeVehicleService realtimeVehicleService(); - - VehicleRentalService vehicleRentalService(); - - VehicleParkingService vehicleParkingService(); - - TransitTuningParameters transitTuningParameters(); - - RaptorTuningParameters raptorTuningParameters(); - - List rideHailingServices(); - - StreetLimitationParametersService streetLimitationParametersService(); - - MeterRegistry meterRegistry(); - - default NearbyPlaceFinder nearbyPlaceFinder() { - return new StreetNearbyPlaceFinder(linkingContextFactory()); - } - - default NearbyStopFinder nearbyStopFinder() { - return graph().hasStreets - ? StreetNearbyStopFinder.of(linkingContextFactory()).build() - : new StraightLineNearbyStopFinder(transitService()::findRegularStopsByBoundingBox); - } - - FlexParameters flexParameters(); - - VectorTileConfig vectorTileConfig(); - - ViaCoordinateTransferFactory viaTransferResolver(); - - TriasApiParameters triasApiParameters(); - - OjpApiParameters ojpApiParameters(); - - GtfsApiParameters gtfsApiParameters(); - - TransmodelAPIParameters transmodelAPIParameters(); - - /* Sandbox modules */ - - @Nullable - CarpoolingService carpoolingService(); - - @Nullable - DataOverlayParameterBindings dataOverlayParameterBindings(); - - @Nullable - default List listExtensionRequestContexts(RouteRequest request) { - var list = new ArrayList(); - if (OTPFeature.DataOverlay.isOn()) { - list.add( - new DataOverlayContext( - dataOverlayParameterBindings(), - request.preferences().system().dataOverlay() - ) - ); - } - return list; - } - - @Nullable - ItineraryDecorator emissionItineraryDecorator(); - - StreetDetailsService streetDetailsService(); - - @Nullable - EmpiricalDelayService empiricalDelayService(); - - @Nullable - LuceneIndex lucenceIndex(); - - @Nullable - StopConsolidationService stopConsolidationService(); - - @Nullable - SorlandsbanenNorwayService sorlandsbanenService(); - - @Nullable - GraphQLSchema gtfsSchema(); - - @Nullable - GraphQLSchema transmodelSchema(); - - FareService fareService(); - - VertexLinker vertexLinker(); - - LinkingContextFactory linkingContextFactory(); -} diff --git a/application/src/main/java/org/opentripplanner/standalone/config/BuildConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/BuildConfig.java index 2180342530f..e59774438bc 100644 --- a/application/src/main/java/org/opentripplanner/standalone/config/BuildConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/BuildConfig.java @@ -33,12 +33,13 @@ import org.opentripplanner.graph_builder.module.cache.GraphBuildCacheParameters; import org.opentripplanner.graph_builder.module.ned.parameter.DemExtractParameters; import org.opentripplanner.graph_builder.module.ned.parameter.DemExtractParametersList; +import org.opentripplanner.graph_builder.module.osm.EdgeNamer; import org.opentripplanner.graph_builder.module.osm.parameters.OsmExtractParameters; import org.opentripplanner.graph_builder.module.osm.parameters.OsmExtractParametersList; import org.opentripplanner.graph_builder.module.transfer.api.RegularTransferParameters; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer; import org.opentripplanner.gtfs.config.GtfsDefaultParameters; import org.opentripplanner.netex.config.NetexFeedParameters; +import org.opentripplanner.osm.model.CompoundRefTagGroup; import org.opentripplanner.standalone.config.buildconfig.DemConfig; import org.opentripplanner.standalone.config.buildconfig.GraphBuildCacheConfig; import org.opentripplanner.standalone.config.buildconfig.GtfsConfig; @@ -169,6 +170,7 @@ public class BuildConfig implements OtpDataStoreConfig { public final DataOverlayConfig dataOverlay; public final double maxStopToShapeSnapDistance; public final Set boardingLocationTags; + public final List elevatorRefTags; private final GraphBuildCacheConfig cache; public final DemExtractParametersList dem; public final OsmExtractParametersList osm; @@ -206,7 +208,7 @@ public BuildConfig(JsonNode node, String source, boolean logUnusedParams) { public BuildConfig(NodeAdapter root, boolean logUnusedParams) { this.root = root; // Keep this list of BASIC parameters sorted alphabetically on config PARAMETER name - areaVisibility = root + this.areaVisibility = root .of("areaVisibility") .since(V1_5) .summary("Perform visibility calculations.") @@ -217,20 +219,20 @@ public BuildConfig(NodeAdapter root, boolean logUnusedParams) { """ ) .asBoolean(false); - cache = GraphBuildCacheConfig.fromConfig(root); - configVersion = root + this.cache = GraphBuildCacheConfig.fromConfig(root); + this.configVersion = root .of("configVersion") .since(V2_1) .summary("Deployment version of the *" + BUILD_CONFIG_FILENAME + "*.") .description(OtpConfig.CONFIG_VERSION_DESCRIPTION) .asString(null); - dataImportReport = root + this.dataImportReport = root .of("dataImportReport") .since(V2_0) .summary("Generate nice HTML report of Graph errors/warnings") .description("The reports are stored in the same location as the graph.") .asBoolean(false); - distanceBetweenElevationSamples = root + this.distanceBetweenElevationSamples = root .of("distanceBetweenElevationSamples") .since(V2_0) .summary("The distance between elevation samples in meters.") @@ -239,8 +241,8 @@ public BuildConfig(NodeAdapter root, boolean logUnusedParams) { "be smaller than the horizontal resolution of the height data used." ) .asDouble(CompactElevationProfile.DEFAULT_DISTANCE_BETWEEN_SAMPLES_METERS); - elevationBucket = S3BucketConfig.fromConfig(root, "elevationBucket"); - embedRouterConfig = root + this.elevationBucket = S3BucketConfig.fromConfig(root, "elevationBucket"); + this.embedRouterConfig = root .of("embedRouterConfig") .since(V2_0) .summary( @@ -248,7 +250,7 @@ public BuildConfig(NodeAdapter root, boolean logUnusedParams) { "configured over the wire." ) .asBoolean(true); - includeEllipsoidToGeoidDifference = root + this.includeEllipsoidToGeoidDifference = root .of("includeEllipsoidToGeoidDifference") .since(V2_0) .summary( @@ -268,9 +270,9 @@ When set to true (it is false by default), the elevation module will include the ) .asBoolean(false); - islandPruning = IslandPruningConfig.fromConfig(root); + this.islandPruning = IslandPruningConfig.fromConfig(root); - maxDataImportIssuesPerFile = root + this.maxDataImportIssuesPerFile = root .of("maxDataImportIssuesPerFile") .since(V2_0) .summary("When to split the import report.") @@ -284,7 +286,7 @@ When set to true (it is false by default), the elevation module will include the this.regularTransferParameters = RegularTransferConfig.map(root); - maxStopToShapeSnapDistance = root + this.maxStopToShapeSnapDistance = root .of("maxStopToShapeSnapDistance") .since(V2_1) .summary("Maximum distance between route shapes and their stops.") @@ -296,7 +298,7 @@ When set to true (it is false by default), the elevation module will include the """ ) .asDouble(150); - multiThreadElevationCalculations = root + this.multiThreadElevationCalculations = root .of("multiThreadElevationCalculations") .since(V2_0) .summary("Configuring multi-threading during elevation calculations.") @@ -308,7 +310,7 @@ When set to true (it is false by default), the elevation module will include the """ ) .asBoolean(false); - elevationTileCacheSizeMB = root + this.elevationTileCacheSizeMB = root .of("elevationTileCacheSizeMB") .since(V2_10) .summary( @@ -323,7 +325,7 @@ When set to true (it is false by default), the elevation module will include the """ ) .asInt(100); - osmCacheDataInMem = root + this.osmCacheDataInMem = root .of("osmCacheDataInMem") .since(V2_0) .summary("If OSM data should be cached in memory during processing.") @@ -338,7 +340,7 @@ When set to true (it is false by default), the elevation module will include the """ ) .asBoolean(false); - platformEntriesLinking = root + this.platformEntriesLinking = root .of("platformEntriesLinking") .since(V2_0) .summary( @@ -366,24 +368,24 @@ When set to true (it is false by default), the elevation module will include the """ ) .asBoolean(false); - staticParkAndRide = root + this.staticParkAndRide = root .of("staticParkAndRide") .since(V1_5) .summary("Whether we should create car P+R stations from OSM data.") .asBoolean(true); - staticBikeParkAndRide = root + this.staticBikeParkAndRide = root .of("staticBikeParkAndRide") .since(V1_5) .summary("Whether we should create bike P+R stations from OSM data.") .asBoolean(false); - includeInclinedEdgeLevelInfo = root + this.includeInclinedEdgeLevelInfo = root .of("includeInclinedEdgeLevelInfo") .since(V2_9) .summary( "Whether level info for inclined edges should be stored in the graph for use during runtime." ) .asBoolean(false); - subwayAccessTime = root + this.subwayAccessTime = root .of("subwayAccessTime") .since(V1_5) .summary( @@ -411,7 +413,7 @@ to check in to a flight (2-3 hours for international flights) than to alight and { // We need a time zone for setting transit service start and end. Getting the wrong time-zone // will just shift the period with one day, so the consequences is limited. - transitModelTimeZone = root + this.transitModelTimeZone = root .of("transitModelTimeZone") .since(V2_2) .summary("Time zone for the graph.") @@ -420,7 +422,7 @@ to check in to a flight (2-3 hours for international flights) than to alight and ) .asZoneId(null); var confZone = ObjectUtils.ifNotNull(transitModelTimeZone, ZoneId.systemDefault()); - transitServiceStart = root + this.transitServiceStart = root .of("transitServiceStart") .since(V2_0) .summary("Limit the import of transit services to the given START date.") @@ -436,7 +438,7 @@ to check in to a flight (2-3 hours for international flights) than to alight and """ ) .asDateOrRelativePeriod("-P1Y", confZone); - transitServiceEnd = root + this.transitServiceEnd = root .of("transitServiceEnd") .since(V2_0) .summary("Limit the import of transit services to the given end date.") @@ -454,7 +456,7 @@ to check in to a flight (2-3 hours for international flights) than to alight and .asDateOrRelativePeriod("P3Y", confZone); } - transitRouteToStationCentroid = root + this.transitRouteToStationCentroid = root .of("transitRouteToStationCentroid") .since(V2_7) .summary("List stations that should route to centroid.") @@ -475,19 +477,19 @@ to check in to a flight (2-3 hours for international flights) than to alight and ) .asFeedScopedIds(List.of()); - maxAreaNodes = root + this.maxAreaNodes = root .of("maxAreaNodes") .since(V2_1) .summary( "Visibility calculations for an area will not be done if there are more nodes than this limit." ) .asInt(StreetConstants.DEFAULT_MAX_AREA_NODES); - maxElevationPropagationMeters = root + this.maxElevationPropagationMeters = root .of("maxElevationPropagationMeters") .since(V1_5) .summary("The maximum distance to propagate elevation to vertices which have no elevation.") .asInt(2000); - boardingLocationTags = root + this.boardingLocationTags = root .of("boardingLocationTags") .since(V2_2) .summary( @@ -495,6 +497,28 @@ to check in to a flight (2-3 hours for international flights) than to alight and ) .description("[Detailed documentation](BoardingLocations.md)") .asStringSet(List.copyOf(Set.of("ref"))); + elevatorRefTags = root + .of("elevatorRefTags") + .since(V2_10) + .summary("Groups of OSM tags whose values are combined into an elevator id.") + .description( + """ + Each group is a list of one or more OSM tag keys. If every tag in a group is present + on an elevator node/way, their values are joined with ':' (in the given order) into + one id. A group with a single tag key produces a plain id. If any tag in a group is + missing, that group produces no id. If more than one group is configured, the first + one (in the given order) that produces an id is used as the elevator's id.""" + ) + .asObjects(List.of(), node -> + CompoundRefTagGroup.of( + node + .of("tagGroup") + .since(V2_10) + .summary("The ordered OSM tag keys whose values are combined into one id.") + .asStringList(List.of()) + .toArray(String[]::new) + ) + ); var localFileNamePatternsConfig = root .of("localFileNamePatterns") @@ -513,7 +537,7 @@ that we support remote input files (cloud storage or arbitrary URLs) not all dat """ ) .asObject(); - gtfsLocalFilePattern = localFileNamePatternsConfig + this.gtfsLocalFilePattern = localFileNamePatternsConfig .of("gtfs") .since(V2_0) .summary("Patterns for matching GTFS zip-files or directories.") @@ -524,7 +548,7 @@ that we support remote input files (cloud storage or arbitrary URLs) not all dat """ ) .asPattern(DEFAULT_GTFS_PATTERN); - netexLocalFilePattern = localFileNamePatternsConfig + this.netexLocalFilePattern = localFileNamePatternsConfig .of("netex") .since(V2_0) .summary("Patterns for matching NeTEx zip files or directories.") @@ -535,7 +559,7 @@ that we support remote input files (cloud storage or arbitrary URLs) not all dat """ ) .asPattern(DEFAULT_NETEX_PATTERN); - osmLocalFilePattern = localFileNamePatternsConfig + this.osmLocalFilePattern = localFileNamePatternsConfig .of("osm") .since(V2_0) .summary("Pattern for matching Open Street Map input files.") @@ -546,7 +570,7 @@ that we support remote input files (cloud storage or arbitrary URLs) not all dat """ ) .asPattern(DEFAULT_OSM_PATTERN); - demLocalFilePattern = localFileNamePatternsConfig + this.demLocalFilePattern = localFileNamePatternsConfig .of("dem") .since(V2_0) .summary("Pattern for matching elevation DEM files.") @@ -558,19 +582,19 @@ that we support remote input files (cloud storage or arbitrary URLs) not all dat ) .asPattern(DEFAULT_DEM_PATTERN); - graph = root + this.graph = root .of("graph") .since(V2_0) .summary("URI to the graph object file for reading and writing.") .description("The file is created or overwritten if OTP saves the graph to the file.") .asUri(null); - streetGraph = root + this.streetGraph = root .of("streetGraph") .since(V2_0) .summary("URI to the street graph object file for reading and writing.") .description("The file is created or overwritten if OTP saves the graph to the file") .asUri(null); - buildReportDir = root + this.buildReportDir = root .of("buildReportDir") .since(V2_0) .summary("URI to the directory where the graph build report should be written to.") @@ -582,7 +606,7 @@ that we support remote input files (cloud storage or arbitrary URLs) not all dat ) .asUri(null); - stopConsolidation = root + this.stopConsolidation = root .of("stopConsolidationFile") .since(V2_5) .summary( @@ -590,15 +614,15 @@ that we support remote input files (cloud storage or arbitrary URLs) not all dat ) .asUri(null); - osmDefaults = OsmConfig.mapOsmDefaults(root, "osmDefaults"); - osm = OsmConfig.mapOsmConfig(root, "osm", osmDefaults); - demDefaults = DemConfig.mapDemDefaultsConfig(root, "demDefaults"); - dem = DemConfig.mapDemConfig(root, "dem", demDefaults); - emission = EmissionConfig.mapEmissionsConfig("emission", root); - empiricalDelay = EmpiricalDelayConfig.mapEmpiricalDelayConfig("empiricalDelay", root); - netexDefaults = NetexConfig.mapNetexDefaultParameters(root, "netexDefaults"); - gtfsDefaults = GtfsConfig.mapGtfsDefaultParameters(root, "gtfsDefaults"); - transitFeeds = TransitFeedConfig.mapTransitFeeds( + this.osmDefaults = OsmConfig.mapOsmDefaults(root, "osmDefaults"); + this.osm = OsmConfig.mapOsmConfig(root, "osm", osmDefaults); + this.demDefaults = DemConfig.mapDemDefaultsConfig(root, "demDefaults"); + this.dem = DemConfig.mapDemConfig(root, "dem", demDefaults); + this.emission = EmissionConfig.mapEmissionsConfig("emission", root); + this.empiricalDelay = EmpiricalDelayConfig.mapEmpiricalDelayConfig("empiricalDelay", root); + this.netexDefaults = NetexConfig.mapNetexDefaultParameters(root, "netexDefaults"); + this.gtfsDefaults = GtfsConfig.mapGtfsDefaultParameters(root, "gtfsDefaults"); + this.transitFeeds = TransitFeedConfig.mapTransitFeeds( root, "transitFeeds", netexDefaults, @@ -606,11 +630,11 @@ that we support remote input files (cloud storage or arbitrary URLs) not all dat ); // List of complex parameters - fareConfig = FaresConfiguration.fromConfig(root, "fares"); - edgeNamer = EdgeNamerFactory.fromConfig(root, "osmNaming"); - dataOverlay = DataOverlayConfigMapper.map(root, "dataOverlay"); + this.fareConfig = FaresConfiguration.fromConfig(root, "fares"); + this.edgeNamer = EdgeNamerFactory.fromConfig(root, "osmNaming"); + this.dataOverlay = DataOverlayConfigMapper.map(root, "dataOverlay"); - gsConfig = GsConfig.fromConfig(root, "gsConfig"); + this.gsConfig = GsConfig.fromConfig(root, "gsConfig"); if (logUnusedParams && LOG.isWarnEnabled()) { root.logAllWarnings(LOG::warn); diff --git a/application/src/main/java/org/opentripplanner/standalone/config/ConfigModel.java b/application/src/main/java/org/opentripplanner/standalone/config/ConfigModel.java index 1b221272f9b..78f7e0b4cc2 100644 --- a/application/src/main/java/org/opentripplanner/standalone/config/ConfigModel.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/ConfigModel.java @@ -131,10 +131,10 @@ public static void initializeOtpFeatures(OtpConfig otpConfig) { */ public void abortOnUnknownParameters() { if ( - (otpConfig.hasUnknownParameters() || - buildConfig.hasUnknownParameters() || - routerConfig.hasUnknownParameters() || - debugUiConfig.hasUnknownParameters()) + otpConfig.hasUnknownParameters() || + buildConfig.hasUnknownParameters() || + routerConfig.hasUnknownParameters() || + debugUiConfig.hasUnknownParameters() ) { throw new OtpAppException( "Configuration contains unknown parameters (see above for details). " + diff --git a/application/src/main/java/org/opentripplanner/standalone/config/OtpConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/OtpConfig.java index bae00137b2f..0001efea8e8 100644 --- a/application/src/main/java/org/opentripplanner/standalone/config/OtpConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/OtpConfig.java @@ -20,16 +20,16 @@ public class OtpConfig { * This description is shared for otp-config, build-config and router-config. */ public static final String CONFIG_VERSION_DESCRIPTION = """ - The config-version is a parameter which each OTP deployment may set to be able to query the - OTP server and verify that it uses the correct version of the config. The version should be - injected into the config in the (continuous) deployment pipeline. How this is done, is up to - the deployment. + The config-version is a parameter which each OTP deployment may set to be able to query the + OTP server and verify that it uses the correct version of the config. The version should be + injected into the config in the (continuous) deployment pipeline. How this is done, is up to + the deployment. - The config-version has no effect on OTP, and is provided as is on the API. There is no syntax - or format check on the version and it can be any string. + The config-version has no effect on OTP, and is provided as is on the API. There is no syntax + or format check on the version and it can be any string. - Be aware that OTP uses the config embedded in the loaded graph if no new config is provided. - """; + Be aware that OTP uses the config embedded in the loaded graph if no new config is provided. + """; private static final Logger LOG = LoggerFactory.getLogger(OtpConfig.class); diff --git a/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/DemConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/DemConfig.java index 9d68a907d11..65fb4d0ff2f 100644 --- a/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/DemConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/DemConfig.java @@ -66,25 +66,23 @@ private static DemExtractParametersBuilder mapGenericDemParameters( String documentationAddition ) { var docDefaults = DemExtractParameters.DEFAULT; - return defaults - .copyOf() - .withElevationUnitMultiplier( - node - .of("elevationUnitMultiplier") - .since(V2_3) - .summary( - "Specify a multiplier to convert elevation units from source to meters." + - documentationAddition - ) - .description( - """ - Unit conversion multiplier for elevation values. No conversion needed if the elevation - values are defined in meters in the source data. If, for example, decimetres are used - in the source data, this should be set to 0.1. - """ - ) - .docDefaultValue(docDefaults.elevationUnitMultiplier()) - .asDouble(defaults.elevationUnitMultiplier()) - ); + return defaults.copyOf().withElevationUnitMultiplier( + node + .of("elevationUnitMultiplier") + .since(V2_3) + .summary( + "Specify a multiplier to convert elevation units from source to meters." + + documentationAddition + ) + .description( + """ + Unit conversion multiplier for elevation values. No conversion needed if the elevation + values are defined in meters in the source data. If, for example, decimetres are used + in the source data, this should be set to 0.1. + """ + ) + .docDefaultValue(docDefaults.elevationUnitMultiplier()) + .asDouble(defaults.elevationUnitMultiplier()) + ); } } diff --git a/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/RegularTransferConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/RegularTransferConfig.java index 1a1b4097f64..77e8fcc631f 100644 --- a/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/RegularTransferConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/RegularTransferConfig.java @@ -104,6 +104,18 @@ private static TransferParametersForMode mapParametersForMode(NodeAdapter c) { c .of("maxTransferDuration") .summary("This overwrites the default `maxTransferDuration` for the given mode.") + .description( + """ + A car or a bike can cover a much larger distance than walking within the same duration. + Reusing this value would reduce the search radius, calculating fewer transfers and + decreases the graph memory usage. + + If it isn't known which stops actually allow cars/bikes, combine a lower value here with + `carsAllowedStopMaxTransferDuration` or `bikesAllowedStopMaxTransferDuration` as a + compromise: this bounds memory usage for stops in general, while the allowed-stop field + still supplies a longer range for the stops it is known to be needed for. + """ + ) .since(V2_7) .asDuration(TransferParametersForMode.DEFAULT_MAX_DURATION) ); @@ -111,26 +123,21 @@ private static TransferParametersForMode mapParametersForMode(NodeAdapter c) { c .of("carsAllowedStopMaxTransferDuration") .summary( - "This is used for specifying a `maxTransferDuration` value to use with transfers between stops which are visited by trips that allow cars." + """ + This is used for specifying a `maxTransferDuration` value to use with transfers between + stops which are visited by trips that allow cars. + """ ) .description( """ - This parameter configures additional transfers to be calculated for the specified mode only between stops that have trips with cars. - The transfers are calculated for the mode in a range based on the given duration. - By default, these transfers are not calculated unless specified for a mode with this field. - - Calculating transfers only between stops that have trips with cars can be useful with car ferries, for example. - Using transit with cars can only occur between certain stops. - These kinds of stops require support for loading cars into ferries, for example. - The default transfers are calculated based on a configurable range (configurable by using the `maxTransferDuration` field) - which limits transfers from stops to only be calculated to other stops that are in range. - When compared to walking, using a car can cover larger distances within the same duration specified in the `maxTransferDuration` field. - This can lead to large amounts of transfers calculated between stops that do not require car transfers between them. - This in turn can lead to a large increase in memory for the stored graph, depending on the data used in the graph. - - For cars, using this parameter in conjunction with `disableDefaultTransfers` allows calculating transfers only between relevant stops. - For bikes, using this parameter can enable transfers between ferry stops that would normally not be in range. - In Finland this is useful for bike routes that use ferries near the Turku archipelago, for example. + Configures a separate `maxTransferDuration` for the given mode, used only for transfers + between stops visited by trips that allow cars (e.g. car ferries), instead of the given + mode's `maxTransferDuration`. + + This can also be configured for other modes. For example, for bikes, this can enable + transfers between ferry stops that would otherwise be out of range, since car ferries + usually also allow bikes. This is useful for bike routes using ferries near the Turku + archipelago in Finland, for example. """ ) .since(V2_7) @@ -140,21 +147,20 @@ The default transfers are calculated based on a configurable range (configurable c .of("bikesAllowedStopMaxTransferDuration") .summary( - "This is used for specifying a `maxTransferDuration` value to use with transfers between stops which are visited by trips that allow bikes." + """ + This is used for specifying a `maxTransferDuration` value to use with transfers between + stops which are visited by trips that allow bikes. + """ ) .description( """ - This parameter configures additional transfers to be calculated for the specified mode only between stops that have trips with bikes. - The transfers are calculated for the mode in a range based on the given duration. - By default, these transfers are not calculated unless specified for a mode with this field. - - When compared to walking, using a bike can cover larger distances within the same duration specified in the `maxTransferDuration` field. - This can lead to large amounts of transfers calculated between stops that do not require bike transfers between them. - This in turn can lead to a large increase in memory for the stored graph, depending on the data used in the graph. + Configures a separate `maxTransferDuration` for the given mode, used only for transfers + between stops visited by trips that allow bikes, instead of the given mode's + `maxTransferDuration`. - For bikes, using this parameter in conjunction with `disableDefaultTransfers` allows calculating transfers only between stops - which have trips which allow carrying bikes. This avoids storing and calculating transfers which are never used so the transit search - can be faster compared to the default transfers. + In combination with the mode's `maxTransferDuration` you can include transfers for bikes + between all stops in a smaller radius, and use a larger radius for transfers between + stops where bikes are explicit allowed. """ ) .since(V2_9) @@ -167,12 +173,12 @@ The default transfers are calculated based on a configurable range (configurable .summary("This disables default transfer calculations.") .description( """ - The default transfers are calculated based on a configurable range (configurable by using the `maxTransferDuration` field) - which limits transfers from stops to only be calculated to other stops that are in range. - This parameter disables these transfers. - A motivation to disable default transfers could be related to using the `carsAllowedStopMaxTransferDuration` field which only - calculates transfers between stops that have trips with cars, or `bikesAllowedStopMaxTransferDuration` field for bikes. - For example, when using the `carsAllowedStopMaxTransferDuration` field with cars, the default transfers can be redundant. + By default, transfers are calculated between all stop pairs within the given mode's + `maxTransferDuration`. This parameter disables that default calculation for the mode. + + This is used together with `carsAllowedStopMaxTransferDuration` or + `bikesAllowedStopMaxTransferDuration`, so that only the restricted, relevant transfers are + calculated. """ ) .since(V2_7) diff --git a/application/src/main/java/org/opentripplanner/standalone/config/framework/file/ConfigFileRedactor.java b/application/src/main/java/org/opentripplanner/standalone/config/framework/file/ConfigFileRedactor.java index 9bebd56066e..1efc9161999 100644 --- a/application/src/main/java/org/opentripplanner/standalone/config/framework/file/ConfigFileRedactor.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/framework/file/ConfigFileRedactor.java @@ -33,15 +33,13 @@ public static String toRedactedString(JsonNode node) { /** Note that this method destructively modifies the node and its children in place. */ private static void redactSecretsRecursive(JsonNode node) { if (node.isObject()) { - node - .properties() - .forEach(entry -> { - if (entry.getValue().isObject() || entry.getValue().isArray()) { - redactSecretsRecursive(entry.getValue()); - } else if (REDACT_KEYS.contains(entry.getKey())) { - entry.setValue(new TextNode("********")); - } - }); + node.properties().forEach(entry -> { + if (entry.getValue().isObject() || entry.getValue().isArray()) { + redactSecretsRecursive(entry.getValue()); + } else if (REDACT_KEYS.contains(entry.getKey())) { + entry.setValue(new TextNode("********")); + } + }); } else if (node.isArray()) { for (JsonNode element : node) { redactSecretsRecursive(element); diff --git a/application/src/main/java/org/opentripplanner/standalone/config/framework/json/OtpVersion.java b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/OtpVersion.java index 1a07c9ff605..329b9a2608f 100644 --- a/application/src/main/java/org/opentripplanner/standalone/config/framework/json/OtpVersion.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/OtpVersion.java @@ -4,6 +4,7 @@ public enum OtpVersion { /** @deprecated Replace this and remove when not in use. */ @Deprecated NA("na"), + V1_5("1.5"), V2_0("2.0"), V2_1("2.1"), diff --git a/application/src/main/java/org/opentripplanner/standalone/config/framework/json/ParameterBuilder.java b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/ParameterBuilder.java index 60c56f95853..bd0e4a787d0 100644 --- a/application/src/main/java/org/opentripplanner/standalone/config/framework/json/ParameterBuilder.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/ParameterBuilder.java @@ -171,16 +171,18 @@ public String asString(String defaultValue) { } public Set asStringSet(Collection defaultValue) { - List dft = (defaultValue instanceof List) - ? (List) defaultValue - : List.copyOf(defaultValue); + List dft = + defaultValue instanceof List + ? (List) defaultValue + : List.copyOf(defaultValue); return Set.copyOf(ofArrayAsList(STRING, dft, JsonNode::asText)); } public List asStringList(Collection defaultValue) { - List dft = (defaultValue instanceof List) - ? (List) defaultValue - : List.copyOf(defaultValue); + List dft = + defaultValue instanceof List + ? (List) defaultValue + : List.copyOf(defaultValue); return ofArrayAsList(STRING, dft, JsonNode::asText); } @@ -249,9 +251,8 @@ public > Set asEnumSet(Class enumClass) { } public > Set asEnumSet(Class enumClass, Collection defaultValues) { - List dft = (defaultValues instanceof List) - ? (List) defaultValues - : List.copyOf(defaultValues); + List dft = + defaultValues instanceof List ? (List) defaultValues : List.copyOf(defaultValues); info.withOptional(dft.toString()).withEnumSet(enumClass); List> optionalList = buildAndListSimpleArrayElements(List.of(), it -> parseOptionalEnum(it.asText(), enumClass) @@ -519,7 +520,9 @@ private T ofOptionalString( var node = build(); return exist() ? mapper.apply(node.asText()) - : (defaultValueAsString == null ? null : mapper.apply(defaultValueAsString)); + : defaultValueAsString == null + ? null + : mapper.apply(defaultValueAsString); } private List ofArrayAsList( diff --git a/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/WarmupConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/WarmupConfig.java index e63f8477afb..99aa38299c5 100644 --- a/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/WarmupConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/WarmupConfig.java @@ -115,8 +115,16 @@ private static WgsCoordinate mapCoordinate( String noun ) { var node = parent.of(name).since(V2_10).summary(summary).asObject(); - double lat = node.of("lat").since(V2_10).summary("Latitude of the " + noun + ".").asDouble(); - double lon = node.of("lon").since(V2_10).summary("Longitude of the " + noun + ".").asDouble(); + double lat = node + .of("lat") + .since(V2_10) + .summary("Latitude of the " + noun + ".") + .asDouble(); + double lon = node + .of("lon") + .since(V2_10) + .summary("Longitude of the " + noun + ".") + .asDouble(); return new WgsCoordinate(lat, lon); } } diff --git a/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriSXUpdaterConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriSXUpdaterConfig.java index a1b7123467d..088007243fd 100644 --- a/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriSXUpdaterConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriSXUpdaterConfig.java @@ -10,13 +10,13 @@ public class SiriSXUpdaterConfig { static final String URL_DESCRIPTION = """ - Use the file protocol to set a directory for reading updates from a directory. The file - loader will look for xml files: '*.xml' in the configured directory. The files are - renamed by the loader when processed: + Use the file protocol to set a directory for reading updates from a directory. The file + loader will look for xml files: '*.xml' in the configured directory. The files are + renamed by the loader when processed: -     _a.xml_   ➞   _a.xml.inProgress_   ➞   _a.xml.ok_   or   _a.xml.failed_ +     _a.xml_   ➞   _a.xml.inProgress_   ➞   _a.xml.ok_   or   _a.xml.failed_ - """; + """; public static SiriSXUpdaterParameters create(String configRef, NodeAdapter c) { return new SiriSXUpdaterParameters( diff --git a/application/src/main/java/org/opentripplanner/standalone/config/routerequest/TransferConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerequest/TransferConfig.java index ec078bad360..eb6a44080e5 100644 --- a/application/src/main/java/org/opentripplanner/standalone/config/routerequest/TransferConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerequest/TransferConfig.java @@ -11,14 +11,13 @@ class TransferConfig { static void mapTransferPreferences(NodeAdapter c, TransferPreferences.Builder tx) { var dft = tx.original(); - tx - .withNonpreferredCost( - c - .of("nonpreferredTransferPenalty") - .since(V2_0) - .summary("Penalty (in seconds) for using a non-preferred transfer.") - .asInt(dft.nonpreferredCost()) - ) + tx.withNonpreferredCost( + c + .of("nonpreferredTransferPenalty") + .since(V2_0) + .summary("Penalty (in seconds) for using a non-preferred transfer.") + .asInt(dft.nonpreferredCost()) + ) .withCost( c .of("transferPenalty") diff --git a/application/src/main/java/org/opentripplanner/standalone/config/sandbox/DataOverlayParametersMapper.java b/application/src/main/java/org/opentripplanner/standalone/config/sandbox/DataOverlayParametersMapper.java index 272684cc2f2..9b59ed515d8 100644 --- a/application/src/main/java/org/opentripplanner/standalone/config/sandbox/DataOverlayParametersMapper.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/sandbox/DataOverlayParametersMapper.java @@ -12,8 +12,7 @@ public static DataOverlayParameters map(NodeAdapter c) { var builder = new DataOverlayParametersBuilder(); for (String param : DataOverlayParameters.parametersAsString()) { - c - .of(param) + c.of(param) .since(NA) .summary("TODO") .asDoubleOptional() diff --git a/application/src/main/java/org/opentripplanner/standalone/config/sandbox/FlexConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/sandbox/FlexConfig.java index 2857875831d..fc3748ae7be 100644 --- a/application/src/main/java/org/opentripplanner/standalone/config/sandbox/FlexConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/sandbox/FlexConfig.java @@ -13,14 +13,14 @@ public class FlexConfig implements FlexParameters { private static final FlexParameters DEFAULT = FlexParameters.defaultValues(); public static final String ACCESS_EGRESS_DESCRIPTION = """ - If you have multiple overlapping flex zones the high default value can lead to performance problems. - A lower value means faster routing. - - Depending on your service this might be what you want to do anyway: many flex services are used - by passengers with mobility problems so offering a long walk might be problematic. In other words, - if you can walk 45 minutes to a flex stop/zone you're unlikely to be the target audience for those - services. - """; + If you have multiple overlapping flex zones the high default value can lead to performance problems. + A lower value means faster routing. + + Depending on your service this might be what you want to do anyway: many flex services are used + by passengers with mobility problems so offering a long walk might be problematic. In other words, + if you can walk 45 minutes to a flex stop/zone you're unlikely to be the target audience for those + services. + """; private final Duration maxTransferDuration; private final Duration maxFlexTripDuration; diff --git a/application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplication.java b/application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplication.java index 9e111d63e5e..24c8545459d 100644 --- a/application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplication.java +++ b/application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplication.java @@ -118,7 +118,7 @@ public class ConstructApplication { var scheduledRaptorTransitData = new RaptorTransitData( transitRepository.getRaptorTransitData() ); - var scheduledTripCalendars = transitRepository.copyTripCalendarForRealTimeUpdates(); + var scheduledTripCalendars = transitRepository.getTripCalendar(); ConstructApplicationFactory.Builder builder = DaggerConstructApplicationFactory.builder(); this.factory = builder diff --git a/application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationFactory.java b/application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationFactory.java index c2a1e716587..d93d21bf8b9 100644 --- a/application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationFactory.java +++ b/application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationFactory.java @@ -71,7 +71,7 @@ import org.opentripplanner.transfer.regular.configure.TransferServiceModule; import org.opentripplanner.transit.configure.StaticTransitService; import org.opentripplanner.transit.configure.TransitModule; -import org.opentripplanner.transit.model.calendar.DefaultTripCalendars; +import org.opentripplanner.transit.model.calendar.TripCalendars; import org.opentripplanner.transit.repository.TimetableRepository; import org.opentripplanner.transit.repository.TimetableRepositorySnapshot; import org.opentripplanner.transit.service.TransitRepository; @@ -251,7 +251,7 @@ Builder stopConsolidationRepository( Builder scheduledRaptorTransitData(RaptorTransitData scheduledRaptorTransitData); @BindsInstance - Builder scheduledTripCalendars(DefaultTripCalendars tripCalendars); + Builder scheduledTripCalendars(TripCalendars tripCalendars); ConstructApplicationFactory build(); } diff --git a/application/src/main/java/org/opentripplanner/standalone/configure/RequestScopedFactory.java b/application/src/main/java/org/opentripplanner/standalone/configure/RequestScopedFactory.java index 74ffb85f3df..a59b893db45 100644 --- a/application/src/main/java/org/opentripplanner/standalone/configure/RequestScopedFactory.java +++ b/application/src/main/java/org/opentripplanner/standalone/configure/RequestScopedFactory.java @@ -3,8 +3,10 @@ import dagger.Subcomponent; import javax.annotation.Nullable; import org.opentripplanner.apis.gtfs.GtfsApiParameters; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.transmodel.TransmodelAPIParameters; import org.opentripplanner.apis.transmodel.TransmodelGraphQLSchema; +import org.opentripplanner.apis.transmodel.TransmodelRequestContext; import org.opentripplanner.ext.geocoder.LuceneIndex; import org.opentripplanner.ext.ojp.parameters.OjpApiParameters; import org.opentripplanner.ext.ojp.parameters.TriasApiParameters; @@ -18,7 +20,6 @@ import org.opentripplanner.service.vehiclerental.VehicleRentalService; import org.opentripplanner.service.worldenvelope.WorldEnvelopeService; import org.opentripplanner.standalone.api.HttpRequestScoped; -import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.standalone.config.DebugUiConfig; import org.opentripplanner.standalone.config.routerconfig.VectorTileConfig; import org.opentripplanner.street.graph.Graph; @@ -43,8 +44,6 @@ public interface RequestScopedFactory { TransitAlertService transitAlertService(); - OtpServerRequestContext createServerContext(); - Graph graph(); RouteRequest defaultRouteRequest(); @@ -80,6 +79,10 @@ public interface RequestScopedFactory { RoutingService routingService(); + TransmodelRequestContext transmodelRequestContext(); + + GtfsGraphQLRequestContext graphQLRequestContext(); + @Subcomponent.Builder interface Builder { RequestScopedFactory build(); diff --git a/application/src/main/java/org/opentripplanner/standalone/configure/RequestScopedModule.java b/application/src/main/java/org/opentripplanner/standalone/configure/RequestScopedModule.java index 6733d93bb99..24f4751ceb9 100644 --- a/application/src/main/java/org/opentripplanner/standalone/configure/RequestScopedModule.java +++ b/application/src/main/java/org/opentripplanner/standalone/configure/RequestScopedModule.java @@ -7,15 +7,16 @@ import java.util.List; import javax.annotation.Nullable; import org.opentripplanner.apis.gtfs.GtfsApiParameters; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.configure.GtfsSchema; import org.opentripplanner.apis.transmodel.TransmodelAPIParameters; import org.opentripplanner.apis.transmodel.TransmodelGraphQLSchema; +import org.opentripplanner.apis.transmodel.TransmodelRequestContext; import org.opentripplanner.apis.transmodel.configure.TransmodelSchema; import org.opentripplanner.ext.carpooling.CarpoolingService; import org.opentripplanner.ext.dataoverlay.configuration.DataOverlayParameterBindings; import org.opentripplanner.ext.empiricaldelay.EmpiricalDelayService; import org.opentripplanner.ext.flex.FlexParameters; -import org.opentripplanner.ext.geocoder.LuceneIndex; import org.opentripplanner.ext.interactivelauncher.api.LauncherRequestDecorator; import org.opentripplanner.ext.ojp.parameters.OjpApiParameters; import org.opentripplanner.ext.ojp.parameters.TriasApiParameters; @@ -26,6 +27,11 @@ import org.opentripplanner.framework.transaction.api.RepositoryHandle; import org.opentripplanner.framework.transaction.api.TransactionScope; import org.opentripplanner.framework.transaction.configure.TransitDomain; +import org.opentripplanner.place.NearbyPlaceFinder; +import org.opentripplanner.place.NearbyStopFinder; +import org.opentripplanner.place.nearbystopfinder.StraightLineNearbyStopFinder; +import org.opentripplanner.place.nearbystopfinder.StreetNearbyStopFinder; +import org.opentripplanner.place.placefinder.StreetNearbyPlaceFinder; import org.opentripplanner.raptor.configure.RaptorConfig; import org.opentripplanner.routing.algorithm.filterchain.ext.EmissionDecorator; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; @@ -39,19 +45,16 @@ import org.opentripplanner.routing.via.ViaCoordinateTransferFactory; import org.opentripplanner.service.realtimevehicles.RealtimeVehicleRepository; import org.opentripplanner.service.realtimevehicles.RealtimeVehicleRepositorySnapshot; +import org.opentripplanner.service.realtimevehicles.RealtimeVehicleService; +import org.opentripplanner.service.realtimevehicles.internal.DefaultRealtimeVehicleService; import org.opentripplanner.service.streetdetails.StreetDetailsService; import org.opentripplanner.service.vehicleparking.VehicleParkingService; import org.opentripplanner.service.vehiclerental.VehicleRentalService; -import org.opentripplanner.service.worldenvelope.WorldEnvelopeService; import org.opentripplanner.standalone.api.HttpRequestScoped; -import org.opentripplanner.standalone.api.OtpServerRequestContext; -import org.opentripplanner.standalone.config.DebugUiConfig; import org.opentripplanner.standalone.config.RouterConfig; import org.opentripplanner.standalone.config.routerconfig.TransitRoutingConfig; import org.opentripplanner.standalone.config.routerconfig.VectorTileConfig; -import org.opentripplanner.standalone.server.DefaultServerRequestContext; import org.opentripplanner.street.graph.Graph; -import org.opentripplanner.street.linking.VertexLinker; import org.opentripplanner.street.service.StreetLimitationParametersService; import org.opentripplanner.transfer.regular.RegularTransferService; import org.opentripplanner.transit.repository.TimetableRepository; @@ -209,92 +212,89 @@ static RoutingService routingService( ); } + /** + * Pre-assembled request context for the Transmodel API's GraphQL data fetchers. + */ @Provides @HttpRequestScoped - static OtpServerRequestContext serverRequestContext( - RouterConfig routerConfig, - DebugUiConfig debugUiConfig, - RaptorConfig raptorConfig, + static TransmodelRequestContext transmodelRequestContext( + RoutingService routingService, + TransitService transitService, + TransitAlertService transitAlertService, + @Nullable EmpiricalDelayService empiricalDelayService, + RouteRequest defaultRouteRequest, + VehicleRentalService vehicleRentalService, + VehicleParkingService vehicleParkingService, Graph graph, + RegularTransferService transferService, + StreetDetailsService streetDetailsService, LinkingContextFactory linkingContextFactory, - VertexLinker vertexLinker, - TransactionScope transactionScope, + StreetLimitationParametersService streetLimitationParametersService + ) { + return new TransmodelRequestContext( + routingService, + transitService, + transitAlertService, + empiricalDelayService, + defaultRouteRequest, + vehicleRentalService, + vehicleParkingService, + graph, + transferService, + streetDetailsService, + linkingContextFactory, + streetLimitationParametersService + ); + } + + /** + * Pre-assembled request context for the GTFS API's GraphQL data fetchers. + */ + @Provides + @HttpRequestScoped + static GtfsGraphQLRequestContext graphQLRequestContext( + RoutingService routingService, TransitService transitService, TransitAlertService transitAlertService, - RouteRequest defaultRequest, - VectorTileConfig vectorTileConfig, - GtfsApiParameters gtfsApiConfig, - TransmodelAPIParameters transmodelAPIParameters, - OjpApiParameters ojpApiParameters, - TriasApiParameters triasApiParameters, RegularTransferService transferService, - WorldEnvelopeService worldEnvelopeService, + FareService fareService, + VehicleRentalService vehicleRentalService, + VehicleParkingService vehicleParkingService, RepositoryHandle< RealtimeVehicleRepositorySnapshot, RealtimeVehicleRepository > realtimeVehicleRepositoryHandle, - VehicleRentalService vehicleRentalService, - VehicleParkingService vehicleParkingService, - List rideHailingServices, - ViaCoordinateTransferFactory viaTransferResolver, - @Nullable CarpoolingService carpoolingService, - @Nullable DataOverlayParameterBindings dataOverlayParameterBindings, - @Nullable StopConsolidationService stopConsolidationService, - StreetLimitationParametersService streetLimitationParametersService, - @Nullable @EmissionDecorator ItineraryDecorator emissionItineraryDecorator, - StreetDetailsService streetDetailsService, + TransactionScope transactionScope, @Nullable @GtfsSchema GraphQLSchema gtfsSchema, - @Nullable @TransmodelSchema GraphQLSchema transmodelSchema, - @Nullable EmpiricalDelayService empiricalDelayService, - @Nullable SorlandsbanenNorwayService sorlandsbanenService, - @Nullable LuceneIndex luceneIndex, - FareService fareService + Graph graph, + LinkingContextFactory linkingContextFactory, + RouteRequest defaultRouteRequest ) { - var transitRoutingConfig = routerConfig.transitTuningConfig(); - var flexParameters = routerConfig.flexParameters(); - var realtimeVehicleSnapshot = realtimeVehicleRepositoryHandle.repositorySnapshot( transactionScope ); - - return new DefaultServerRequestContext( - debugUiConfig, - fareService, - flexParameters, - graph, - linkingContextFactory, - Metrics.globalRegistry, - ojpApiParameters, - raptorConfig, + RealtimeVehicleService realtimeVehicleService = new DefaultRealtimeVehicleService( realtimeVehicleSnapshot, - rideHailingServices, - defaultRequest, - streetLimitationParametersService, - transferService, - transactionScope, - transitRoutingConfig, + transitService + ); + NearbyPlaceFinder nearbyPlaceFinder = new StreetNearbyPlaceFinder(linkingContextFactory); + NearbyStopFinder nearbyStopFinder = graph.hasStreets + ? StreetNearbyStopFinder.of(linkingContextFactory).build() + : new StraightLineNearbyStopFinder(transitService::findRegularStopsByBoundingBox); + + return new GtfsGraphQLRequestContext( + routingService, transitService, transitAlertService, - triasApiParameters, - gtfsApiConfig, - vectorTileConfig, - vehicleParkingService, + transferService, + fareService, vehicleRentalService, - vertexLinker, - viaTransferResolver, - worldEnvelopeService, - // Optional Sandbox services - carpoolingService, - dataOverlayParameterBindings, - emissionItineraryDecorator, - streetDetailsService, - empiricalDelayService, - luceneIndex, + vehicleParkingService, + realtimeVehicleService, gtfsSchema, - transmodelSchema, - sorlandsbanenService, - stopConsolidationService, - transmodelAPIParameters + nearbyPlaceFinder, + nearbyStopFinder, + defaultRouteRequest ); } } diff --git a/application/src/main/java/org/opentripplanner/standalone/server/AlertMetrics.java b/application/src/main/java/org/opentripplanner/standalone/server/AlertMetrics.java index 3f0ef75dd68..004797e858d 100644 --- a/application/src/main/java/org/opentripplanner/standalone/server/AlertMetrics.java +++ b/application/src/main/java/org/opentripplanner/standalone/server/AlertMetrics.java @@ -72,10 +72,10 @@ private Iterable> summarizeAlerts(TransitAlertService ale .stream() .collect( ImmutableListMultimap.< - TransitAlert, - AlertTags, - TransitAlert - >flatteningToImmutableListMultimap(AlertTags::of, Stream::of) + TransitAlert, + AlertTags, + TransitAlert + >flatteningToImmutableListMultimap(AlertTags::of, Stream::of) ); return taggedAlerts .keySet() diff --git a/application/src/main/java/org/opentripplanner/standalone/server/DaggerToJerseyBridge.java b/application/src/main/java/org/opentripplanner/standalone/server/DaggerToJerseyBridge.java index 14b5cf62ae7..120597f03ee 100644 --- a/application/src/main/java/org/opentripplanner/standalone/server/DaggerToJerseyBridge.java +++ b/application/src/main/java/org/opentripplanner/standalone/server/DaggerToJerseyBridge.java @@ -6,8 +6,10 @@ import org.glassfish.jersey.internal.inject.AbstractBinder; import org.glassfish.jersey.process.internal.RequestScoped; import org.opentripplanner.apis.gtfs.GtfsApiParameters; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.transmodel.TransmodelAPIParameters; import org.opentripplanner.apis.transmodel.TransmodelGraphQLSchema; +import org.opentripplanner.apis.transmodel.TransmodelRequestContext; import org.opentripplanner.ext.geocoder.LuceneIndex; import org.opentripplanner.ext.ojp.parameters.OjpApiParameters; import org.opentripplanner.ext.ojp.parameters.TriasApiParameters; @@ -19,7 +21,6 @@ import org.opentripplanner.service.vehicleparking.VehicleParkingService; import org.opentripplanner.service.vehiclerental.VehicleRentalService; import org.opentripplanner.service.worldenvelope.WorldEnvelopeService; -import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.standalone.config.DebugUiConfig; import org.opentripplanner.standalone.config.routerconfig.VectorTileConfig; import org.opentripplanner.standalone.configure.RequestScopedFactory; @@ -29,8 +30,7 @@ /** * Bridges the Dagger-managed {@link RequestScopedFactory} into HK2/Jersey: the component itself, - * {@link OtpServerRequestContext} (grab-bag of everything not yet migrated), and individual - * request-scoped services (currently just {@link TransitService}) that resources can inject + * plus individual request-scoped services (e.g. {@link TransitService}) that resources can inject * directly with {@code @Context}. *

* All bindings are scoped {@code .in(RequestScoped.class)} — Jersey's own per-actual-HTTP-request @@ -65,7 +65,6 @@ protected void configure() { // Binding for all request-scoped services used by resources bridge(factory, RequestScopedFactory::transitService, TransitService.class); bridge(factory, RequestScopedFactory::transitAlertService, TransitAlertService.class); - bridge(factory, RequestScopedFactory::createServerContext, OtpServerRequestContext.class); bridge(factory, RequestScopedFactory::graph, Graph.class); bridge(factory, RequestScopedFactory::defaultRouteRequest, RouteRequest.class); bridge(factory, RequestScopedFactory::vehicleParkingService, VehicleParkingService.class); @@ -83,6 +82,8 @@ protected void configure() { bridge(factory, RequestScopedFactory::ojpApiParameters, OjpApiParameters.class); bridge(factory, RequestScopedFactory::triasApiParameters, TriasApiParameters.class); bridge(factory, RequestScopedFactory::routingService, RoutingService.class); + bridge(factory, RequestScopedFactory::transmodelRequestContext, TransmodelRequestContext.class); + bridge(factory, RequestScopedFactory::graphQLRequestContext, GtfsGraphQLRequestContext.class); } /** diff --git a/application/src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java b/application/src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java deleted file mode 100644 index fc4c17e8d5b..00000000000 --- a/application/src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java +++ /dev/null @@ -1,424 +0,0 @@ -package org.opentripplanner.standalone.server; - -import graphql.schema.GraphQLSchema; -import io.micrometer.core.instrument.MeterRegistry; -import java.util.List; -import javax.annotation.Nullable; -import org.opentripplanner.apis.gtfs.GtfsApiParameters; -import org.opentripplanner.apis.gtfs.configure.GtfsSchema; -import org.opentripplanner.apis.transmodel.TransmodelAPIParameters; -import org.opentripplanner.apis.transmodel.configure.TransmodelSchema; -import org.opentripplanner.ext.carpooling.CarpoolingService; -import org.opentripplanner.ext.dataoverlay.configuration.DataOverlayParameterBindings; -import org.opentripplanner.ext.empiricaldelay.EmpiricalDelayService; -import org.opentripplanner.ext.flex.FlexParameters; -import org.opentripplanner.ext.geocoder.LuceneIndex; -import org.opentripplanner.ext.ojp.parameters.OjpApiParameters; -import org.opentripplanner.ext.ojp.parameters.TriasApiParameters; -import org.opentripplanner.ext.ridehailing.RideHailingService; -import org.opentripplanner.ext.sorlandsbanen.SorlandsbanenNorwayService; -import org.opentripplanner.ext.stopconsolidation.StopConsolidationService; -import org.opentripplanner.framework.transaction.api.TransactionScope; -import org.opentripplanner.raptor.api.request.RaptorTuningParameters; -import org.opentripplanner.raptor.configure.RaptorConfig; -import org.opentripplanner.routing.algorithm.filterchain.ext.EmissionDecorator; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitTuningParameters; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripSchedule; -import org.opentripplanner.routing.api.RoutingService; -import org.opentripplanner.routing.api.request.RouteRequest; -import org.opentripplanner.routing.fares.FareService; -import org.opentripplanner.routing.linking.LinkingContextFactory; -import org.opentripplanner.routing.service.DefaultRoutingService; -import org.opentripplanner.routing.services.TransitAlertService; -import org.opentripplanner.routing.via.ViaCoordinateTransferFactory; -import org.opentripplanner.service.realtimevehicles.RealtimeVehicleRepositorySnapshot; -import org.opentripplanner.service.realtimevehicles.RealtimeVehicleService; -import org.opentripplanner.service.realtimevehicles.internal.DefaultRealtimeVehicleService; -import org.opentripplanner.service.streetdetails.StreetDetailsService; -import org.opentripplanner.service.vehicleparking.VehicleParkingService; -import org.opentripplanner.service.vehiclerental.VehicleRentalService; -import org.opentripplanner.service.worldenvelope.WorldEnvelopeService; -import org.opentripplanner.standalone.api.HttpRequestScoped; -import org.opentripplanner.standalone.api.OtpServerRequestContext; -import org.opentripplanner.standalone.config.DebugUiConfig; -import org.opentripplanner.standalone.config.routerconfig.TransitRoutingConfig; -import org.opentripplanner.standalone.config.routerconfig.VectorTileConfig; -import org.opentripplanner.street.graph.Graph; -import org.opentripplanner.street.linking.VertexLinker; -import org.opentripplanner.street.service.StreetLimitationParametersService; -import org.opentripplanner.transfer.regular.RegularTransferService; -import org.opentripplanner.transit.service.TransitService; - -@HttpRequestScoped -public class DefaultServerRequestContext implements OtpServerRequestContext { - - // Keep sort order: Main services, optional services and writable/none final fields - // All 3 sections is sorted alphabetically. - - private final DebugUiConfig debugUiConfig; - private final TransactionScope transactionScope; - private final FareService fareService; - private final FlexParameters flexParameters; - private final Graph graph; - private final LinkingContextFactory linkingContextFactory; - private final MeterRegistry meterRegistry; - private final RaptorConfig raptorConfig; - private final RealtimeVehicleRepositorySnapshot realtimeVehicleSnapshot; - private final List rideHailingServices; - private final RouteRequest routeRequestDefaults; - private final StreetLimitationParametersService streetLimitationParametersService; - private final RegularTransferService transferService; - private final TransitRoutingConfig transitRoutingConfig; - private final TransitService transitService; - private final TransitAlertService transitAlertService; - private final VectorTileConfig vectorTileConfig; - private final VehicleParkingService vehicleParkingService; - private final VehicleRentalService vehicleRentalService; - private final ViaCoordinateTransferFactory viaTransferResolver; - private final WorldEnvelopeService worldEnvelopeService; - - /* Optional fields */ - - @Nullable - private final CarpoolingService carpoolingService; - - @Nullable - private final DataOverlayParameterBindings dataOverlayParameterBindings; - - @Nullable - private final ItineraryDecorator emissionItineraryDecorator; - - private final StreetDetailsService streetDetailsService; - - @Nullable - private final EmpiricalDelayService empiricalDelayService; - - @Nullable - private final LuceneIndex luceneIndex; - - @Nullable - private final GraphQLSchema gtfsSchema; - - @Nullable - private final GraphQLSchema transmodelSchema; - - @Nullable - private final SorlandsbanenNorwayService sorlandsbanenService; - - @Nullable - private final StopConsolidationService stopConsolidationService; - - private final TriasApiParameters triasApiParameters; - - private final OjpApiParameters ojpApiParameters; - - private final GtfsApiParameters gtfsApiParameters; - - private final TransmodelAPIParameters transmodelAPIParameters; - - private final VertexLinker vertexLinker; - - /* Lazy initialized fields */ - - private RouteRequest defaultRouteRequestWithTimeSet = null; - - /** - * Create a server context valid for one http request only! - * Make sure all mutable components are copied/cloned before calling this constructor. - */ - public DefaultServerRequestContext( - // Keep the same order as in the field declaration - DebugUiConfig debugUiConfig, - FareService fareService, - FlexParameters flexParameters, - Graph graph, - LinkingContextFactory linkingContextFactory, - MeterRegistry meterRegistry, - OjpApiParameters ojpApiParameters, - RaptorConfig raptorConfig, - RealtimeVehicleRepositorySnapshot realtimeVehicleSnapshot, - List rideHailingServices, - RouteRequest routeRequestDefaults, - StreetLimitationParametersService streetLimitationParametersService, - RegularTransferService transferService, - TransactionScope transactionScope, - TransitRoutingConfig transitRoutingConfig, - TransitService transitService, - TransitAlertService transitAlertService, - TriasApiParameters triasApiParameters, - GtfsApiParameters gtfsApiParameters, - VectorTileConfig vectorTileConfig, - VehicleParkingService vehicleParkingService, - VehicleRentalService vehicleRentalService, - VertexLinker vertexLinker, - ViaCoordinateTransferFactory viaTransferResolver, - WorldEnvelopeService worldEnvelopeService, - @Nullable CarpoolingService carpoolingService, - @Nullable DataOverlayParameterBindings dataOverlayParameterBindings, - @Nullable @EmissionDecorator ItineraryDecorator emissionItineraryDecorator, - StreetDetailsService streetDetailsService, - @Nullable EmpiricalDelayService empiricalDelayService, - @Nullable LuceneIndex luceneIndex, - @Nullable @GtfsSchema GraphQLSchema gtfsSchema, - @Nullable @TransmodelSchema GraphQLSchema transmodelSchema, - @Nullable SorlandsbanenNorwayService sorlandsbanenService, - @Nullable StopConsolidationService stopConsolidationService, - TransmodelAPIParameters transmodelAPIParameters - ) { - this.debugUiConfig = debugUiConfig; - this.flexParameters = flexParameters; - this.fareService = fareService; - this.graph = graph; - this.linkingContextFactory = linkingContextFactory; - this.meterRegistry = meterRegistry; - this.ojpApiParameters = ojpApiParameters; - this.raptorConfig = raptorConfig; - this.realtimeVehicleSnapshot = realtimeVehicleSnapshot; - this.rideHailingServices = rideHailingServices; - this.routeRequestDefaults = routeRequestDefaults; - this.streetLimitationParametersService = streetLimitationParametersService; - this.transferService = transferService; - this.transactionScope = transactionScope; - this.transitRoutingConfig = transitRoutingConfig; - this.transitService = transitService; - this.transitAlertService = transitAlertService; - this.transmodelSchema = transmodelSchema; - this.triasApiParameters = triasApiParameters; - this.gtfsApiParameters = gtfsApiParameters; - this.vectorTileConfig = vectorTileConfig; - this.vehicleParkingService = vehicleParkingService; - this.vehicleRentalService = vehicleRentalService; - this.vertexLinker = vertexLinker; - this.viaTransferResolver = viaTransferResolver; - this.worldEnvelopeService = worldEnvelopeService; - - // Optional fields - this.carpoolingService = carpoolingService; - this.dataOverlayParameterBindings = dataOverlayParameterBindings; - this.emissionItineraryDecorator = emissionItineraryDecorator; - this.streetDetailsService = streetDetailsService; - this.empiricalDelayService = empiricalDelayService; - this.luceneIndex = luceneIndex; - this.gtfsSchema = gtfsSchema; - this.sorlandsbanenService = sorlandsbanenService; - this.stopConsolidationService = stopConsolidationService; - this.transmodelAPIParameters = transmodelAPIParameters; - } - - @Override - public DebugUiConfig debugUiConfig() { - return debugUiConfig; - } - - @Override - public TransactionScope transactionScope() { - return transactionScope; - } - - @Override - public RouteRequest defaultRouteRequest() { - return routeRequestDefaults; - } - - @Override - public RaptorConfig raptorConfig() { - return raptorConfig; - } - - @Override - public Graph graph() { - return graph; - } - - @Override - public TransitService transitService() { - return transitService; - } - - @Override - public TransitAlertService transitAlertService() { - return transitAlertService; - } - - @Override - public RoutingService routingService() { - return new DefaultRoutingService( - transitService, - transitAlertService, - graph, - raptorConfig, - meterRegistry, - streetLimitationParametersService, - vehicleRentalService, - streetDetailsService, - transferService, - flexParameters, - rideHailingServices, - dataOverlayParameterBindings, - sorlandsbanenService, - viaTransferResolver, - carpoolingService, - emissionItineraryDecorator, - stopConsolidationService, - linkingContextFactory, - transitRoutingConfig, - transitRoutingConfig - ); - } - - @Override - public RegularTransferService transferService() { - return transferService; - } - - @Override - public WorldEnvelopeService worldEnvelopeService() { - return worldEnvelopeService; - } - - @Override - public RealtimeVehicleService realtimeVehicleService() { - return new DefaultRealtimeVehicleService(realtimeVehicleSnapshot, transitService); - } - - @Override - public VehicleRentalService vehicleRentalService() { - return vehicleRentalService; - } - - @Override - public VehicleParkingService vehicleParkingService() { - return vehicleParkingService; - } - - @Override - public TransitTuningParameters transitTuningParameters() { - return transitRoutingConfig; - } - - @Override - public RaptorTuningParameters raptorTuningParameters() { - return transitRoutingConfig; - } - - @Override - public List rideHailingServices() { - return rideHailingServices; - } - - @Nullable - @Override - public GraphQLSchema gtfsSchema() { - return gtfsSchema; - } - - @Nullable - @Override - public GraphQLSchema transmodelSchema() { - return transmodelSchema; - } - - @Override - public StopConsolidationService stopConsolidationService() { - return stopConsolidationService; - } - - @Override - public StreetLimitationParametersService streetLimitationParametersService() { - return streetLimitationParametersService; - } - - @Override - public MeterRegistry meterRegistry() { - return meterRegistry; - } - - @Override - public FlexParameters flexParameters() { - return flexParameters; - } - - @Override - public VectorTileConfig vectorTileConfig() { - return vectorTileConfig; - } - - @Override - public ViaCoordinateTransferFactory viaTransferResolver() { - return viaTransferResolver; - } - - @Override - public TriasApiParameters triasApiParameters() { - return triasApiParameters; - } - - @Override - public OjpApiParameters ojpApiParameters() { - return ojpApiParameters; - } - - @Override - public GtfsApiParameters gtfsApiParameters() { - return gtfsApiParameters; - } - - @Override - public TransmodelAPIParameters transmodelAPIParameters() { - return transmodelAPIParameters; - } - - @Nullable - @Override - public CarpoolingService carpoolingService() { - return carpoolingService; - } - - @Nullable - @Override - public DataOverlayParameterBindings dataOverlayParameterBindings() { - return dataOverlayParameterBindings; - } - - @Nullable - @Override - public LuceneIndex lucenceIndex() { - return luceneIndex; - } - - @Override - public ItineraryDecorator emissionItineraryDecorator() { - return emissionItineraryDecorator; - } - - @Override - public StreetDetailsService streetDetailsService() { - return streetDetailsService; - } - - @Override - public EmpiricalDelayService empiricalDelayService() { - return empiricalDelayService; - } - - @Nullable - public SorlandsbanenNorwayService sorlandsbanenService() { - return sorlandsbanenService; - } - - @Override - public FareService fareService() { - return fareService; - } - - @Override - public VertexLinker vertexLinker() { - return vertexLinker; - } - - @Override - public LinkingContextFactory linkingContextFactory() { - return linkingContextFactory; - } -} diff --git a/application/src/main/java/org/opentripplanner/standalone/server/EtagRequestFilter.java b/application/src/main/java/org/opentripplanner/standalone/server/EtagRequestFilter.java index d8a0d4074a4..9d0f921bfb3 100644 --- a/application/src/main/java/org/opentripplanner/standalone/server/EtagRequestFilter.java +++ b/application/src/main/java/org/opentripplanner/standalone/server/EtagRequestFilter.java @@ -50,7 +50,7 @@ private static boolean isEligibleForEtag( var statusCode = response.getStatus(); if (statusCode >= 200 && statusCode < 300 && HttpMethod.GET.matches(request.getMethod())) { String cacheControl = response.getHeaderString(HEADER_CACHE_CONTROL); - return (cacheControl == null || !cacheControl.contains(DIRECTIVE_NO_STORE)); + return cacheControl == null || !cacheControl.contains(DIRECTIVE_NO_STORE); } return false; diff --git a/application/src/main/java/org/opentripplanner/streetadapter/StreetSearchRequestMapper.java b/application/src/main/java/org/opentripplanner/streetadapter/StreetSearchRequestMapper.java index 675cb003ba2..c46ee547130 100644 --- a/application/src/main/java/org/opentripplanner/streetadapter/StreetSearchRequestMapper.java +++ b/application/src/main/java/org/opentripplanner/streetadapter/StreetSearchRequestMapper.java @@ -103,8 +103,7 @@ public static StreetSearchRequestBuilder mapToTransferRequest(RouteRequest reque // private methods private static void mapWheelchair(WheelchairRequest.Builder b, WheelchairPreferences wheelchair) { - b - .withStop(mapAccessibility(wheelchair.stop())) + b.withStop(mapAccessibility(wheelchair.stop())) .withElevator(mapAccessibility(wheelchair.elevator())) .withMaxSlope(wheelchair.maxSlope()) .withSlopeExceededReluctance(wheelchair.slopeExceededReluctance()) @@ -123,8 +122,7 @@ private static AccessibilityRequest mapAccessibility(AccessibilityPreferences st } private static void mapWalk(WalkRequest.Builder b, WalkPreferences pref) { - b - .withSpeed(pref.speed()) + b.withSpeed(pref.speed()) .withReluctance(pref.reluctance()) .withStairsReluctance(pref.stairsReluctance()) .withStairsTimeFactor(pref.stairsTimeFactor()) @@ -137,8 +135,7 @@ private static void mapEscalator(EscalatorRequest.Builder b, EscalatorPreference } private static void mapBike(BikeRequest.Builder b, BikePreferences preferences) { - b - .withReluctance(preferences.reluctance()) + b.withReluctance(preferences.reluctance()) .withSpeed(preferences.speed()) .withParking(b2 -> mapParking(b2, preferences.parking())) .withRental(b2 -> mapRental(b2, preferences.rental())) @@ -158,8 +155,7 @@ private static TimeSlopeSafetyTriangle mapTriangle( } private static void mapCar(CarRequest.Builder b, CarPreferences car) { - b - .withReluctance(car.reluctance()) + b.withReluctance(car.reluctance()) .withParking(b2 -> mapParking(b2, car.parking())) .withRental(b2 -> mapRental(b2, car.rental())) .withPickupTime(car.pickupTime()) @@ -169,8 +165,7 @@ private static void mapCar(CarRequest.Builder b, CarPreferences car) { } private static void mapScooter(ScooterRequest.Builder b, ScooterPreferences scooter) { - b - .withSpeed(scooter.speed()) + b.withSpeed(scooter.speed()) .withReluctance(scooter.reluctance()) .withRental(b2 -> mapRental(b2, scooter.rental())) .withOptimizeType(scooter.optimizeType()) @@ -182,8 +177,7 @@ private static void mapVehicleWalking( VehicleWalkingRequest.Builder b, VehicleWalkingPreferences walking ) { - b - .withSpeed(walking.speed()) + b.withSpeed(walking.speed()) .withReluctance(walking.reluctance()) .withStairsReluctance(walking.stairsReluctance()) .withMountDismountCost(walking.mountDismountCost()) @@ -191,8 +185,7 @@ private static void mapVehicleWalking( } private static void mapRental(RentalRequest.Builder b, VehicleRentalPreferences rental) { - b - .withPickupTime(rental.pickupTime()) + b.withPickupTime(rental.pickupTime()) .withPickupCost(rental.pickupCost()) .withDropOffTime(rental.dropOffTime()) .withDropOffCost(rental.dropOffCost()) @@ -209,8 +202,7 @@ private static void mapRental(RentalRequest.Builder b, VehicleRentalPreferences } private static void mapParking(ParkingRequest.Builder b, VehicleParkingPreferences pref) { - b - .withUnpreferredTagCost(pref.unpreferredVehicleParkingTagCost()) + b.withUnpreferredTagCost(pref.unpreferredVehicleParkingTagCost()) .withFilter(mapParkingFilter(pref.filter())) .withPreferred(mapParkingFilter(pref.preferred())) .withTime(pref.time()) @@ -230,8 +222,7 @@ private static List mapTagSelect(List selec } private static void mapElevator(ElevatorRequest.Builder b, ElevatorPreferences elevator) { - b - .withBoardCost(elevator.boardCost()) + b.withBoardCost(elevator.boardCost()) .withBoardSlack(elevator.boardSlack()) .withHopTime(elevator.hopTime()) .withReluctance(elevator.reluctance()) diff --git a/application/src/main/java/org/opentripplanner/transfer/constrained/raptoradaptor/ConstrainedBoardingSearch.java b/application/src/main/java/org/opentripplanner/transfer/constrained/raptoradaptor/ConstrainedBoardingSearch.java index c5c458612c3..7c4fb6b2465 100644 --- a/application/src/main/java/org/opentripplanner/transfer/constrained/raptoradaptor/ConstrainedBoardingSearch.java +++ b/application/src/main/java/org/opentripplanner/transfer/constrained/raptoradaptor/ConstrainedBoardingSearch.java @@ -18,7 +18,8 @@ * and the "to" point in the reverse search. */ public final class ConstrainedBoardingSearch - implements RaptorConstrainedBoardingSearch { + implements RaptorConstrainedBoardingSearch +{ /** * Abort the search after looking at 5 valid boardings. In the case where this happens, one of @@ -221,7 +222,8 @@ private boolean findTimetableTripInfo( } private static final class NoopRaptorConstrainedBoardingSearch - implements RaptorConstrainedBoardingSearch { + implements RaptorConstrainedBoardingSearch + { @Override public boolean transferExistTargetStop(int targetStopPos) { diff --git a/application/src/main/java/org/opentripplanner/transfer/constrained/raptoradaptor/ConstrainedTransferBoarding.java b/application/src/main/java/org/opentripplanner/transfer/constrained/raptoradaptor/ConstrainedTransferBoarding.java index c9dacd06c72..8fc99116ad3 100644 --- a/application/src/main/java/org/opentripplanner/transfer/constrained/raptoradaptor/ConstrainedTransferBoarding.java +++ b/application/src/main/java/org/opentripplanner/transfer/constrained/raptoradaptor/ConstrainedTransferBoarding.java @@ -7,8 +7,8 @@ /** * A boarding event passed to Raptor to perform a boarding. */ -public class ConstrainedTransferBoarding - implements RaptorBoardOrAlightEvent { +public class ConstrainedTransferBoarding implements + RaptorBoardOrAlightEvent { private final RaptorTransferConstraint constraint; private final int tripIndex; diff --git a/application/src/main/java/org/opentripplanner/transfer/regular/index/PreCachedRaptorTransferIndex.java b/application/src/main/java/org/opentripplanner/transfer/regular/index/PreCachedRaptorTransferIndex.java index 1fe73f86d79..b32933c7f11 100644 --- a/application/src/main/java/org/opentripplanner/transfer/regular/index/PreCachedRaptorTransferIndex.java +++ b/application/src/main/java/org/opentripplanner/transfer/regular/index/PreCachedRaptorTransferIndex.java @@ -60,9 +60,15 @@ class PreCachedRaptorTransferIndex implements RaptorTransferIndex { // Create immutable copies of the lists for each stop to make them immutable and faster to iterate //noinspection unchecked - this.forwardTransfers = forwardTransfers.stream().map(List::copyOf).toArray(List[]::new); + this.forwardTransfers = forwardTransfers + .stream() + .map(List::copyOf) + .toArray(List[]::new); //noinspection unchecked - this.reversedTransfers = reversedTransfers.stream().map(List::copyOf).toArray(List[]::new); + this.reversedTransfers = reversedTransfers + .stream() + .map(List::copyOf) + .toArray(List[]::new); } public Collection getForwardTransfers(int stopIndex) { diff --git a/application/src/main/java/org/opentripplanner/transfer/regular/internal/DefaultTransferService.java b/application/src/main/java/org/opentripplanner/transfer/regular/internal/DefaultTransferService.java index a908b08582a..2915a38f9b8 100644 --- a/application/src/main/java/org/opentripplanner/transfer/regular/internal/DefaultTransferService.java +++ b/application/src/main/java/org/opentripplanner/transfer/regular/internal/DefaultTransferService.java @@ -14,7 +14,7 @@ */ public class DefaultTransferService implements RegularTransferService { - private static final Logger LOG = LoggerFactory.getLogger(RegularTransferService.class); + private static final Logger LOG = LoggerFactory.getLogger(DefaultTransferService.class); private final TransferRepository transferRepository; diff --git a/application/src/main/java/org/opentripplanner/transfer/regular/model/DefaultRaptorTransfer.java b/application/src/main/java/org/opentripplanner/transfer/regular/model/DefaultRaptorTransfer.java index 8d75351b2cb..3210e7d7bf9 100644 --- a/application/src/main/java/org/opentripplanner/transfer/regular/model/DefaultRaptorTransfer.java +++ b/application/src/main/java/org/opentripplanner/transfer/regular/model/DefaultRaptorTransfer.java @@ -63,9 +63,8 @@ public int hashCode() { public String toString() { String duration = DurationUtils.durationToStr(durationInSeconds()); var modes = transfer.getModes(); - var modesAsString = modes.size() == 1 - ? modes.stream().findFirst().get().toString() - : modes.toString(); + var modesAsString = + modes.size() == 1 ? modes.stream().findFirst().get().toString() : modes.toString(); return String.format( "%s %s %s ~ %d", modesAsString, diff --git a/application/src/main/java/org/opentripplanner/transit/api/request/TransitAlertRequest.java b/application/src/main/java/org/opentripplanner/transit/api/request/TransitAlertRequest.java new file mode 100644 index 00000000000..35edd77deb1 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/api/request/TransitAlertRequest.java @@ -0,0 +1,29 @@ +package org.opentripplanner.transit.api.request; + +import java.util.List; +import org.opentripplanner.routing.alertpatch.TransitAlert; +import org.opentripplanner.transit.model.filter.selector.FilterRequest; +import org.opentripplanner.transit.model.filter.transit.TransitAlertSelectRequest; + +/** + * A request for {@link TransitAlert}s. + *

+ * The request holds a list of filters which are combined with OR semantics: an alert matches if it + * matches at least one of the filters. An empty list of filters matches all alerts. + */ +public class TransitAlertRequest { + + private final List> filters; + + TransitAlertRequest(List> filters) { + this.filters = filters; + } + + public static TransitAlertRequestBuilder of() { + return new TransitAlertRequestBuilder(); + } + + public List> filters() { + return filters; + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/api/request/TransitAlertRequestBuilder.java b/application/src/main/java/org/opentripplanner/transit/api/request/TransitAlertRequestBuilder.java new file mode 100644 index 00000000000..4c08ff61f39 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/api/request/TransitAlertRequestBuilder.java @@ -0,0 +1,21 @@ +package org.opentripplanner.transit.api.request; + +import java.util.List; +import org.opentripplanner.transit.model.filter.selector.FilterRequest; +import org.opentripplanner.transit.model.filter.transit.TransitAlertSelectRequest; + +public class TransitAlertRequestBuilder { + + private List> filters = List.of(); + + public TransitAlertRequestBuilder withFilters( + List> filters + ) { + this.filters = List.copyOf(filters); + return this; + } + + public TransitAlertRequest build() { + return new TransitAlertRequest(filters); + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequest.java b/application/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequest.java index 6f28d675a30..f635ffa5271 100644 --- a/application/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequest.java +++ b/application/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequest.java @@ -4,6 +4,7 @@ import java.util.List; import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.core.model.time.LocalDateRange; +import org.opentripplanner.core.model.time.TimePeriod; import org.opentripplanner.transit.api.model.FilterValues; import org.opentripplanner.transit.model.basic.MainAndSubMode; import org.opentripplanner.transit.model.basic.TransitMode; @@ -22,6 +23,7 @@ public class TripOnServiceDateRequest { private final FilterValues includeServiceDates; private final FilterValues includeServiceDateRanges; + private final FilterValues includeRunningTimePeriods; private final FilterValues includeAgencies; private final FilterValues includeRoutes; private final FilterValues includePatterns; @@ -34,6 +36,7 @@ public class TripOnServiceDateRequest { TripOnServiceDateRequest( FilterValues includeServiceDates, FilterValues includeServiceDateRanges, + FilterValues includeRunningTimePeriods, FilterValues includeAgencies, FilterValues includeRoutes, FilterValues includePatterns, @@ -45,6 +48,7 @@ public class TripOnServiceDateRequest { ) { this.includeServiceDates = includeServiceDates; this.includeServiceDateRanges = includeServiceDateRanges; + this.includeRunningTimePeriods = includeRunningTimePeriods; this.includeAgencies = includeAgencies; this.includeRoutes = includeRoutes; this.includePatterns = includePatterns; @@ -95,6 +99,13 @@ public FilterValues includeServiceDateRanges() { return includeServiceDateRanges; } + /** + * Periods of time in which the trip must be running, according to its schedule. + */ + public FilterValues includeRunningTimePeriods() { + return includeRunningTimePeriods; + } + public FilterValues includeModes() { List modesToInclude = null; if (!filters.isEmpty()) { diff --git a/application/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequestBuilder.java b/application/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequestBuilder.java index ccde3b1f543..71c5cd69448 100644 --- a/application/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequestBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequestBuilder.java @@ -4,6 +4,7 @@ import java.util.List; import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.core.model.time.LocalDateRange; +import org.opentripplanner.core.model.time.TimePeriod; import org.opentripplanner.transit.api.model.FilterValues; import org.opentripplanner.transit.model.filter.selector.FilterRequest; import org.opentripplanner.transit.model.filter.transit.TripOnServiceDateSelectRequest; @@ -47,6 +48,10 @@ public class TripOnServiceDateRequestBuilder { "includeServiceDateRanges", List.of() ); + private FilterValues includeRunningTimePeriods = FilterValues.ofEmptyIsEverything( + "includeRunningTimePeriods", + List.of() + ); private List> filters = List.of(); public TripOnServiceDateRequestBuilder withIncludeAgencies(FilterValues agencies) { @@ -106,6 +111,13 @@ public TripOnServiceDateRequestBuilder withIncludeServiceDateRanges( return this; } + public TripOnServiceDateRequestBuilder withIncludeRunningTimePeriods( + FilterValues runningTimePeriods + ) { + this.includeRunningTimePeriods = runningTimePeriods; + return this; + } + public TripOnServiceDateRequestBuilder withFilters( List> filters ) { @@ -117,6 +129,7 @@ public TripOnServiceDateRequest build() { return new TripOnServiceDateRequest( includeServiceDates, includeServiceDateRanges, + includeRunningTimePeriods, includeAgencies, includeRoutes, includePatterns, diff --git a/application/src/main/java/org/opentripplanner/transit/api/request/TripTimeOnDateRequest.java b/application/src/main/java/org/opentripplanner/transit/api/request/TripTimeOnDateRequest.java index cea81a495bc..a1b168ac098 100644 --- a/application/src/main/java/org/opentripplanner/transit/api/request/TripTimeOnDateRequest.java +++ b/application/src/main/java/org/opentripplanner/transit/api/request/TripTimeOnDateRequest.java @@ -10,6 +10,7 @@ import javax.annotation.Nullable; import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.core.model.time.LocalDateRange; +import org.opentripplanner.core.model.time.TimePeriod; import org.opentripplanner.model.TripTimeOnDate; import org.opentripplanner.transit.api.model.FilterValues; import org.opentripplanner.transit.model.basic.TransitMode; @@ -27,6 +28,7 @@ public class TripTimeOnDateRequest { private final List serviceDateRanges; private final CancellationPolicy cancellationPolicy; + private final FilterValues includeCallTimePeriods; private final FilterValues includeAgencies; private final FilterValues includeRoutes; private final FilterValues excludeAgencies; @@ -48,6 +50,7 @@ public TripTimeOnDateRequest( int numberOfDepartures, Comparator sortOrder, CancellationPolicy cancellationPolicy, + FilterValues includeCallTimePeriods, FilterValues includeAgencies, FilterValues includeRoutes, FilterValues excludeAgencies, @@ -64,6 +67,7 @@ public TripTimeOnDateRequest( this.numberOfDepartures = numberOfDepartures; this.sortOrder = Objects.requireNonNull(sortOrder); this.cancellationPolicy = Objects.requireNonNull(cancellationPolicy); + this.includeCallTimePeriods = includeCallTimePeriods; this.includeAgencies = includeAgencies; this.includeRoutes = includeRoutes; this.excludeAgencies = excludeAgencies; @@ -110,6 +114,16 @@ public CancellationPolicy cancellationPolicy() { return cancellationPolicy; } + /** + * Limit the returned output to the defined periods of time based on when the vehicle is + * scheduled to visit the stop. At least one of the periods has to overlap with the visit at the + * stop, which lasts from the scheduled arrival at the stop until the scheduled departure from + * it. + */ + public FilterValues includeCallTimePeriods() { + return includeCallTimePeriods; + } + public FilterValues includeAgencies() { return includeAgencies; } diff --git a/application/src/main/java/org/opentripplanner/transit/api/request/TripTimeOnDateRequestBuilder.java b/application/src/main/java/org/opentripplanner/transit/api/request/TripTimeOnDateRequestBuilder.java index 928313ca378..5fbf2dabdc8 100644 --- a/application/src/main/java/org/opentripplanner/transit/api/request/TripTimeOnDateRequestBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/api/request/TripTimeOnDateRequestBuilder.java @@ -8,6 +8,7 @@ import javax.annotation.Nullable; import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.core.model.time.LocalDateRange; +import org.opentripplanner.core.model.time.TimePeriod; import org.opentripplanner.model.TripTimeOnDate; import org.opentripplanner.transit.api.model.FilterValues; import org.opentripplanner.transit.model.basic.TransitMode; @@ -20,12 +21,17 @@ public class TripTimeOnDateRequestBuilder { private static final String INCLUDE_AGENCIES = "includeAgencies"; private static final String INCLUDE_ROUTES = "includeRoutes"; + private static final String INCLUDE_CALL_TIME_PERIODS = "includeCallTimePeriods"; private static final String EXCLUDE_AGENCIES = "excludeAgencies"; private static final String INCLUDE_MODES = "includeModes"; private static final String EXCLUDE_ROUTES = "excludeRoutes"; private static final String EXCLUDE_MODES = "excludeModes"; private final Collection stopLocations; private CancellationPolicy cancellationPolicy = CancellationPolicy.NO_CANCELLATIONS; + private FilterValues includeCallTimePeriods = FilterValues.ofNullIsEverything( + INCLUDE_CALL_TIME_PERIODS, + null + ); private FilterValues includeAgencies = FilterValues.ofNullIsEverything( INCLUDE_AGENCIES, null @@ -85,6 +91,21 @@ public TripTimeOnDateRequestBuilder withServiceDateRanges( return this; } + /** + * Only include calls where the vehicle is scheduled to visit the stop during one of the given + * periods. The visit at a stop lasts from the scheduled arrival at the stop until the scheduled + * departure from it. + */ + public TripTimeOnDateRequestBuilder withIncludeCallTimePeriods( + @Nullable Collection callTimePeriods + ) { + this.includeCallTimePeriods = FilterValues.ofNullIsEverything( + INCLUDE_CALL_TIME_PERIODS, + callTimePeriods + ); + return this; + } + public TripTimeOnDateRequestBuilder withIncludeAgencies( @Nullable Collection agencies ) { @@ -154,6 +175,7 @@ public TripTimeOnDateRequest build() { numberOfDepartures, sortOrder, cancellationPolicy, + includeCallTimePeriods, includeAgencies, includeRoutes, excludeAgencies, diff --git a/application/src/main/java/org/opentripplanner/transit/configure/TransitModule.java b/application/src/main/java/org/opentripplanner/transit/configure/TransitModule.java index 1ffdfdb1b7d..0d35a4ab486 100644 --- a/application/src/main/java/org/opentripplanner/transit/configure/TransitModule.java +++ b/application/src/main/java/org/opentripplanner/transit/configure/TransitModule.java @@ -12,7 +12,7 @@ import org.opentripplanner.routing.algorithm.raptoradapter.transit.RaptorTransitData; import org.opentripplanner.standalone.config.ConfigModel; import org.opentripplanner.standalone.configure.RequestScopedFactory; -import org.opentripplanner.transit.model.calendar.DefaultTripCalendars; +import org.opentripplanner.transit.model.calendar.TripCalendars; import org.opentripplanner.transit.repository.DefaultTimetableRepository; import org.opentripplanner.transit.repository.TimetableRepository; import org.opentripplanner.transit.repository.TimetableRepositoryLifecycle; @@ -50,7 +50,7 @@ > timetableRepositoryHandle( TransitRepository transitRepository, @TransitDomain RepositoryRegistry repositoryRegistry, RaptorTransitData scheduledRaptorTransitData, - DefaultTripCalendars tripCalendars + TripCalendars tripCalendars ) { var buffer = new DefaultTimetableRepository(scheduledRaptorTransitData, tripCalendars); var lifecycle = new TimetableRepositoryLifecycle(buffer, parameters.purgeExpiredData(), () -> diff --git a/application/src/main/java/org/opentripplanner/transit/model/basic/NarrowedTransitMode.java b/application/src/main/java/org/opentripplanner/transit/model/basic/NarrowedTransitMode.java index f32576b5b13..366f51fbd59 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/basic/NarrowedTransitMode.java +++ b/application/src/main/java/org/opentripplanner/transit/model/basic/NarrowedTransitMode.java @@ -45,7 +45,7 @@ public static List all() { } public boolean isMainModeOnly() { - return (this.subMode == null && this.replacement == ReplacementRequirement.IGNORED); + return this.subMode == null && this.replacement == ReplacementRequirement.IGNORED; } public MainAndSubMode toMainAndSubMode() { diff --git a/application/src/main/java/org/opentripplanner/transit/model/calendar/DefaultTripCalendars.java b/application/src/main/java/org/opentripplanner/transit/model/calendar/DefaultTripCalendars.java deleted file mode 100644 index 3234028766b..00000000000 --- a/application/src/main/java/org/opentripplanner/transit/model/calendar/DefaultTripCalendars.java +++ /dev/null @@ -1,158 +0,0 @@ -package org.opentripplanner.transit.model.calendar; - -import gnu.trove.set.TIntSet; -import gnu.trove.set.hash.TIntHashSet; -import java.io.Serializable; -import java.time.LocalDate; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import javax.annotation.Nullable; -import org.opentripplanner.core.model.id.FeedScopedId; -import org.opentripplanner.model.calendar.CalendarServiceData; - -/** - * TODO : This class is NOT SAFE for realtime updates. This should be split into a - * snapshot and a mutable version and integrated with the realtime update - * transactions. See https://github.com/opentripplanner/OpenTripPlanner/pull/7689 - * and https://github.com/opentripplanner/OpenTripPlanner/pull/7731#discussion_r3441794468 - */ -public class DefaultTripCalendars implements TripCalendars, Serializable { - - private final CalendarServiceData calendarServiceData; - private final Map serviceCodesRunningForDate; - private final Map serviceCodes; - - private DefaultTripCalendars( - CalendarServiceData calendarServiceData, - Map serviceCodesRunningForDate, - Map serviceCodes - ) { - // TODO, inline the calendarServiceData and copy the maps - this.calendarServiceData = calendarServiceData; - this.serviceCodesRunningForDate = serviceCodesRunningForDate; - this.serviceCodes = serviceCodes; - } - - public DefaultTripCalendars() { - this(new CalendarServiceData(), new HashMap<>(), new HashMap<>()); - } - - /** - * Make the mutable copy. - */ - public DefaultTripCalendars copyOf() { - return new DefaultTripCalendars( - calendarServiceData, - // TODO: The values must be copied as well - new HashMap<>(serviceCodesRunningForDate), - new HashMap<>(serviceCodes) - ); - } - - @Override - public Set listServiceIds() { - return calendarServiceData.getServiceIds(); - } - - @Override - public Set listServiceDates(FeedScopedId serviceId) { - Set dates = new HashSet<>(); - List serviceDates = calendarServiceData.getServiceDatesForServiceId(serviceId); - if (serviceDates != null) { - dates.addAll(serviceDates); - } - return dates; - } - - @Override - public Set listServiceIdsOnServiceDate(LocalDate serviceDate) { - return calendarServiceData.getServiceIdsForDate(serviceDate); - } - - @Override - public boolean isActiveOn(FeedScopedId serviceId, LocalDate serviceDate) { - return calendarServiceData.getServiceIdsForDate(serviceDate).contains(serviceId); - } - - @Override - public Integer getServiceCode(FeedScopedId serviceId) { - // TODO Change this to return an int, it there is no service code for the given serviceId, - // then it is an error. - return serviceCodes.get(serviceId); - } - - /** - * Map from GTFS ServiceIds to integers close to 0. Allows using BitSets instead of - * {@code Set}. An empty Map is created before the Graph is built to allow registering IDs - * from multiple feeds. - */ - public Map getServiceCodes() { - return serviceCodes; - } - - /** - * For all dates in the system get the service codes that run on it. - */ - public Map getServiceCodesRunningForDate() { - return Collections.unmodifiableMap(serviceCodesRunningForDate); - } - - /** - * Get or create a serviceId for a given date. This method is used when a new trip is added from a - * realtime data update. It makes sure the date is in the existing transit service period. - * - * @param serviceDate service date for the added service id - * @return service-id for date if it exists or is created. If the given service date is outside the - * service period {@code null} is returned. - */ - @Nullable - public FeedScopedId getOrCreateServiceIdForDate(LocalDate serviceDate) { - var serviceId = calendarServiceData.getOrCreateServiceIdForDate(serviceDate); - - if (!serviceCodes.containsKey(serviceId)) { - // Calculating new unique serviceCode based on size (!) - final int serviceCode = serviceCodes.size(); - serviceCodes.put(serviceId, serviceCode); - - serviceCodesRunningForDate - .computeIfAbsent(serviceDate, _ -> new TIntHashSet()) - .add(serviceCode); - } - return serviceId; - } - - public void merge(CalendarServiceData data) { - calendarServiceData.add(data); - } - - public Optional startDate() { - return calendarServiceData.getFirstDate(); - } - - public Optional endDate() { - return calendarServiceData.getLastDate(); - } - - public boolean isEmpty() { - return calendarServiceData.getServiceIds().isEmpty(); - } - - public void initializeServiceCodes() { - for (FeedScopedId serviceId : listServiceIds()) { - Integer code = serviceCodes.get(serviceId); - if (code == null) { - continue; - } - for (LocalDate serviceDate : listServiceDates(serviceId)) { - serviceCodesRunningForDate - .computeIfAbsent(serviceDate, ignored -> new TIntHashSet()) - .add(code); - } - } - } -} diff --git a/application/src/main/java/org/opentripplanner/transit/model/calendar/TripCalendars.java b/application/src/main/java/org/opentripplanner/transit/model/calendar/TripCalendars.java index ff9ac92a72c..89cfa925a35 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/calendar/TripCalendars.java +++ b/application/src/main/java/org/opentripplanner/transit/model/calendar/TripCalendars.java @@ -1,25 +1,97 @@ package org.opentripplanner.transit.model.calendar; +import gnu.trove.TCollections; +import gnu.trove.set.TIntSet; +import gnu.trove.set.hash.TIntHashSet; +import java.io.Serializable; import java.time.LocalDate; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.Set; +import java.util.function.Consumer; +import javax.annotation.Nullable; import org.opentripplanner.core.model.id.FeedScopedId; +import org.opentripplanner.model.calendar.CalendarServiceData; +import org.opentripplanner.utils.time.ServiceDateUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * - * - * TODO - Convert return types to List not Set. + * Immutable snapshot of the trip service calendar: which service ids exist, which dates they run + * on, and the small integer service codes used by Raptor. + *

+ * There is no builder: every modification (see {@link #merge}, {@link #withServiceCode}, + * {@link #initializeServiceCodesRunningForDate}, {@link #getOrCreateServiceIdForDate}) returns a new instance + * rather than mutating this one, so callers that hold onto a {@code TripCalendars} keep seeing a + * stable value even while another reference is evolving. A caller that needs a long-lived, + * continuously-updated view (e.g. {@code DefaultTimetableRepository}'s write buffer) just holds a + * plain mutable field and reassigns it as each method returns its result. */ -public interface TripCalendars { +public class TripCalendars implements Serializable { + + private static final String CAL_SERVICE_FEED_ID = "CSID"; + private static final Logger LOG = LoggerFactory.getLogger(TripCalendars.class); + + private final Map> serviceDatesByServiceId; + private final Map> serviceIdsByDate; + private final Map serviceCodesRunningForDate; + private final Map serviceCodes; + + @Nullable + private final LocalDate startDate; + + @Nullable + private final LocalDate endDate; + + private TripCalendars( + Map> serviceDatesByServiceId, + Map> serviceIdsByDate, + Map serviceCodesRunningForDate, + Map serviceCodes + ) { + this.serviceDatesByServiceId = serviceDatesByServiceId; + this.serviceIdsByDate = serviceIdsByDate; + this.serviceCodesRunningForDate = serviceCodesRunningForDate; + this.serviceCodes = serviceCodes; + this.startDate = serviceIdsByDate.keySet().stream().min(LocalDate::compareTo).orElse(null); + this.endDate = serviceIdsByDate.keySet().stream().max(LocalDate::compareTo).orElse(null); + } + + /** An empty trip calendar, with no service ids registered. */ + public static TripCalendars empty() { + // Note: Collections.emptyMap(), not Map.of() — the latter throws NullPointerException on a + // null probe key. + return new TripCalendars( + Collections.emptyMap(), + Collections.emptyMap(), + Collections.emptyMap(), + Collections.emptyMap() + ); + } + /** - * @return all service ids used in the data set. The list + * @return all service ids used in the data set. */ - Set listServiceIds(); + public Set listServiceIds() { + return serviceDatesByServiceId.keySet(); + } /** * @param serviceId the target service id * @return the set of all service dates for which the specified service id is active */ - Set listServiceDates(FeedScopedId serviceId); + public Set listServiceDates(FeedScopedId serviceId) { + Set dates = new HashSet<>(); + List serviceDates = serviceDatesByServiceId.get(serviceId); + if (serviceDates != null) { + dates.addAll(serviceDates); + } + return dates; + } /** * Determine the set of service ids that are active on the specified service date. @@ -27,7 +99,11 @@ public interface TripCalendars { * @param serviceDate the target service date * @return the set of service ids that are active on the specified service date */ - Set listServiceIdsOnServiceDate(LocalDate serviceDate); + public Set listServiceIdsOnServiceDate(LocalDate serviceDate) { + // Note: Collections.emptySet(), not Set.of() — the latter throws NullPointerException on a + // null argument to contains(), and the given serviceId here can be null (e.g. flex trips). + return serviceIdsByDate.getOrDefault(serviceDate, Collections.emptySet()); + } /** * Determine whether the given service id is active on the specified service date. @@ -36,7 +112,9 @@ public interface TripCalendars { * @param serviceDate the target service date * @return {@code true} if the service id is active on the given service date */ - boolean isActiveOn(FeedScopedId serviceId, LocalDate serviceDate); + public boolean isActiveOn(FeedScopedId serviceId, LocalDate serviceDate) { + return listServiceIdsOnServiceDate(serviceDate).contains(serviceId); + } /** * Return the integer service code assigned to the given service id, or {@code null} if the @@ -48,5 +126,247 @@ public interface TripCalendars { * * @return the integer code, or {@code null} if not found */ - Integer getServiceCode(FeedScopedId serviceId); + public Integer getServiceCode(FeedScopedId serviceId) { + return serviceCodes.get(serviceId); + } + + /** + * Map from GTFS ServiceIds to integers close to 0. Allows using BitSets instead of + * {@code Set}. + */ + public Map getServiceCodes() { + return serviceCodes; + } + + /** + * For all dates in the system get the service codes that run on it. + */ + public Map getServiceCodesRunningForDate() { + return serviceCodesRunningForDate; + } + + public Optional startDate() { + return Optional.ofNullable(startDate); + } + + public Optional endDate() { + return Optional.ofNullable(endDate); + } + + public boolean isEmpty() { + return serviceDatesByServiceId.isEmpty(); + } + + /** + * Merge scheduled calendar data into this calendar. Used during graph build only. + * + * @return a new instance with {@code data} merged in. + */ + public TripCalendars merge(CalendarServiceData data) { + Map> newServiceDatesByServiceId = new HashMap<>( + serviceDatesByServiceId + ); + Map> newServiceIdsByDate = deepCopy(serviceIdsByDate); + for (FeedScopedId serviceId : data.getServiceIds()) { + List dates = data + .getServiceDatesForServiceId(serviceId) + .stream() + .sorted() + .toList(); + newServiceDatesByServiceId.put(serviceId, dates); + for (LocalDate date : dates) { + newServiceIdsByDate.computeIfAbsent(date, d -> new HashSet<>()).add(serviceId); + } + } + return new TripCalendars( + Collections.unmodifiableMap(newServiceDatesByServiceId), + freezeServiceIds(newServiceIdsByDate), + serviceCodesRunningForDate, + serviceCodes + ); + } + + /** + * Register {@code code} as the service code for {@code serviceId}. Used during graph build only. + * + * @return a new instance with the service code registered, or this same instance if the service + * id was already registered with this exact code. + */ + public TripCalendars withServiceCode(FeedScopedId serviceId, int code) { + if (Integer.valueOf(code).equals(serviceCodes.get(serviceId))) { + return this; + } + Map updated = new HashMap<>(serviceCodes); + updated.put(serviceId, code); + return new TripCalendars( + serviceDatesByServiceId, + serviceIdsByDate, + serviceCodesRunningForDate, + Collections.unmodifiableMap(updated) + ); + } + + /** + * Compute {@link #getServiceCodesRunningForDate()} from the currently registered service ids + * and service codes. Used once, during graph build, after all scheduled calendar data has been + * merged in and all service codes have been registered. + * + * @return a new instance with {@link #getServiceCodesRunningForDate()} computed. + */ + public TripCalendars initializeServiceCodesRunningForDate() { + Map newServiceCodesRunningForDate = new HashMap<>(); + for (FeedScopedId serviceId : serviceDatesByServiceId.keySet()) { + Integer code = serviceCodes.get(serviceId); + if (code == null) { + continue; + } + List serviceDates = serviceDatesByServiceId.get(serviceId); + for (LocalDate serviceDate : serviceDates) { + newServiceCodesRunningForDate + .computeIfAbsent(serviceDate, ignored -> new TIntHashSet()) + .add(code); + } + } + return new TripCalendars( + serviceDatesByServiceId, + serviceIdsByDate, + freezeServiceCodes(newServiceCodesRunningForDate), + serviceCodes + ); + } + + /** + * Get or create a serviceId for a given date. This method is used when a new trip is added from + * a realtime data update. It makes sure the date is in the existing transit service period, i.e. + * within {@link #startDate()} and {@link #endDate()}. + *

+ * Unlike the other modification methods, this one only produces (and passes to {@code onUpdate}) + * a new instance if the service id was not already registered — the common case, where the same + * date has already been seen by an earlier call, is a pure read with no allocation. + * + * @param serviceDate service date for the added service id + * @param onUpdate callback invoked with the new instance, if and only if a new service id was + * registered + * @return service-id for date if it exists or is created. If the given service date is outside + * the service period {@code null} is returned. + */ + @Nullable + public FeedScopedId getOrCreateServiceIdForDate( + LocalDate serviceDate, + Consumer onUpdate + ) { + if (!isWithinServicePeriod(serviceDate)) { + return null; + } + + FeedScopedId serviceId = new FeedScopedId( + CAL_SERVICE_FEED_ID, + ServiceDateUtils.asCompactString(serviceDate) + ); + if (serviceDatesByServiceId.containsKey(serviceId) && serviceCodes.containsKey(serviceId)) { + return serviceId; + } + + Map> newServiceDatesByServiceId = serviceDatesByServiceId; + Map> newServiceIdsByDate = serviceIdsByDate; + if (!serviceDatesByServiceId.containsKey(serviceId)) { + newServiceDatesByServiceId = withEntry( + serviceDatesByServiceId, + serviceId, + List.of(serviceDate) + ); + newServiceIdsByDate = withAddedServiceId(serviceIdsByDate, serviceDate, serviceId); + LOG.info("Adding serviceId {} to trip calendar", serviceId); + } + + Map newServiceCodes = serviceCodes; + Map newServiceCodesRunningForDate = serviceCodesRunningForDate; + if (!serviceCodes.containsKey(serviceId)) { + // Calculating new unique serviceCode based on size (!) + int serviceCode = serviceCodes.size(); + newServiceCodes = withEntry(serviceCodes, serviceId, serviceCode); + newServiceCodesRunningForDate = withAddedServiceCode( + serviceCodesRunningForDate, + serviceDate, + serviceCode + ); + } + + onUpdate.accept( + new TripCalendars( + newServiceDatesByServiceId, + newServiceIdsByDate, + newServiceCodesRunningForDate, + newServiceCodes + ) + ); + return serviceId; + } + + private boolean isWithinServicePeriod(LocalDate serviceDate) { + if (startDate == null || endDate == null) { + return false; + } + return !serviceDate.isBefore(startDate) && !serviceDate.isAfter(endDate); + } + + private static Map> deepCopy( + Map> serviceIdsByDate + ) { + Map> copy = new HashMap<>(); + serviceIdsByDate.forEach((date, serviceIds) -> copy.put(date, new HashSet<>(serviceIds))); + return copy; + } + + private static Map> freezeServiceIds( + Map> serviceIdsByDate + ) { + Map> frozen = new HashMap<>(); + serviceIdsByDate.forEach((date, serviceIds) -> + frozen.put(date, Collections.unmodifiableSet(serviceIds)) + ); + return Collections.unmodifiableMap(frozen); + } + + private static Map freezeServiceCodes( + Map serviceCodesRunningForDate + ) { + Map frozen = new HashMap<>(); + serviceCodesRunningForDate.forEach((date, codes) -> + frozen.put(date, TCollections.unmodifiableSet(codes)) + ); + return Collections.unmodifiableMap(frozen); + } + + private static Map withEntry(Map map, K key, V value) { + Map copy = new HashMap<>(map); + copy.put(key, value); + return Collections.unmodifiableMap(copy); + } + + private static Map> withAddedServiceId( + Map> serviceIdsByDate, + LocalDate date, + FeedScopedId serviceId + ) { + Map> copy = new HashMap<>(serviceIdsByDate); + Set existing = copy.get(date); + Set updated = existing == null ? new HashSet<>() : new HashSet<>(existing); + updated.add(serviceId); + copy.put(date, Collections.unmodifiableSet(updated)); + return Collections.unmodifiableMap(copy); + } + + private static Map withAddedServiceCode( + Map serviceCodesRunningForDate, + LocalDate date, + int code + ) { + Map copy = new HashMap<>(serviceCodesRunningForDate); + TIntSet existing = copy.get(date); + TIntSet updated = existing == null ? new TIntHashSet() : new TIntHashSet(existing); + updated.add(code); + copy.put(date, TCollections.unmodifiableSet(updated)); + return Collections.unmodifiableMap(copy); + } } diff --git a/application/src/main/java/org/opentripplanner/transit/model/filter/expr/BinaryOperator.java b/application/src/main/java/org/opentripplanner/transit/model/filter/expr/BinaryOperator.java index 62f3fa30f27..474818841a1 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/filter/expr/BinaryOperator.java +++ b/application/src/main/java/org/opentripplanner/transit/model/filter/expr/BinaryOperator.java @@ -28,7 +28,10 @@ String arrayToString(T[] values) { } String colToString(Collection values) { - return values.stream().map(Objects::toString).collect(Collectors.joining(" " + token + " ")); + return values + .stream() + .map(Objects::toString) + .collect(Collectors.joining(" " + token + " ")); } String toString(T a, T b) { diff --git a/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TransitAlertMatcherFactory.java b/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TransitAlertMatcherFactory.java new file mode 100644 index 00000000000..5d717456a37 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TransitAlertMatcherFactory.java @@ -0,0 +1,82 @@ +package org.opentripplanner.transit.model.filter.transit; + +import org.opentripplanner.core.model.time.TimePeriod; +import org.opentripplanner.routing.alertpatch.AlertCause; +import org.opentripplanner.routing.alertpatch.AlertEffect; +import org.opentripplanner.routing.alertpatch.AlertSeverity; +import org.opentripplanner.routing.alertpatch.TransitAlert; +import org.opentripplanner.transit.api.request.TransitAlertRequest; +import org.opentripplanner.transit.model.filter.expr.EqualityMatcher; +import org.opentripplanner.transit.model.filter.expr.ExpressionBuilder; +import org.opentripplanner.transit.model.filter.expr.GenericUnaryMatcher; +import org.opentripplanner.transit.model.filter.expr.Matcher; +import org.opentripplanner.transit.model.filter.selector.SelectorBasedMatcherFactory; + +/** + * A factory for creating matchers for {@link TransitAlert}s. + *

+ * This factory builds a matcher from a {@link TransitAlertRequest} that can be used to filter a + * collection of {@link TransitAlert}s. The filters of the request are combined with OR logic, while + * the criteria within a single selector are combined with AND logic. + */ +public class TransitAlertMatcherFactory { + + /** + * Creates a matcher for {@link TransitAlert}s. + * + * @param request the criteria for filtering alerts. + * @return a matcher for filtering alerts. + */ + public static Matcher of(TransitAlertRequest request) { + ExpressionBuilder expr = ExpressionBuilder.of(); + + if (!request.filters().isEmpty()) { + expr.matches( + SelectorBasedMatcherFactory.of( + request.filters(), + TransitAlertMatcherFactory::buildSelectorMatcher + ) + ); + } + + return expr.build(); + } + + /** + * Builds a matcher from a single {@link TransitAlertSelectRequest}, combining its dimensions with + * AND logic. + */ + private static Matcher buildSelectorMatcher(TransitAlertSelectRequest selector) { + ExpressionBuilder expr = ExpressionBuilder.of(); + + expr.atLeastOneMatch(selector.feeds(), TransitAlertMatcherFactory::feed); + expr.atLeastOneMatch(selector.severityLevels(), TransitAlertMatcherFactory::severity); + expr.atLeastOneMatch(selector.causes(), TransitAlertMatcherFactory::cause); + expr.atLeastOneMatch(selector.effects(), TransitAlertMatcherFactory::effect); + expr.atLeastOneMatch(selector.timePeriods(), TransitAlertMatcherFactory::timePeriod); + + return expr.build(); + } + + static Matcher feed(String feedId) { + return new EqualityMatcher<>("feed", feedId, a -> a.getId().getFeedId()); + } + + static Matcher severity(AlertSeverity severity) { + return new EqualityMatcher<>("severity", severity, TransitAlert::severity); + } + + static Matcher cause(AlertCause cause) { + return new EqualityMatcher<>("cause", cause, TransitAlert::cause); + } + + static Matcher effect(AlertEffect effect) { + return new EqualityMatcher<>("effect", effect, TransitAlert::effect); + } + + static Matcher timePeriod(TimePeriod timePeriod) { + return new GenericUnaryMatcher<>("timePeriod", alert -> + alert.calendar().isActiveDuring(timePeriod) + ); + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TransitAlertSelectRequest.java b/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TransitAlertSelectRequest.java new file mode 100644 index 00000000000..ce7e7ad49fe --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TransitAlertSelectRequest.java @@ -0,0 +1,125 @@ +package org.opentripplanner.transit.model.filter.transit; + +import java.util.List; +import javax.annotation.Nullable; +import org.opentripplanner.core.model.time.TimePeriod; +import org.opentripplanner.routing.alertpatch.AlertCause; +import org.opentripplanner.routing.alertpatch.AlertEffect; +import org.opentripplanner.routing.alertpatch.AlertSeverity; +import org.opentripplanner.routing.alertpatch.TransitAlert; +import org.opentripplanner.transit.api.model.FilterValues; +import org.opentripplanner.utils.tostring.ToStringBuilder; + +/** + * Represents a single selection criterion for filtering {@link TransitAlert}s. + * Criteria within a single request are combined with AND logic: all specified criteria must + * match for the request to match. Unset (null) criteria are ignored (match everything). + */ +public class TransitAlertSelectRequest { + + private final FilterValues feeds; + private final FilterValues severityLevels; + private final FilterValues causes; + private final FilterValues effects; + private final FilterValues timePeriods; + + private TransitAlertSelectRequest(Builder builder) { + this.feeds = FilterValues.ofNullIsEverything("feeds", builder.feeds); + this.severityLevels = FilterValues.ofNullIsEverything("severityLevels", builder.severityLevels); + this.causes = FilterValues.ofNullIsEverything("causes", builder.causes); + this.effects = FilterValues.ofNullIsEverything("effects", builder.effects); + this.timePeriods = FilterValues.ofNullIsEverything("timePeriods", builder.timePeriods); + } + + public static Builder of() { + return new Builder(); + } + + public FilterValues feeds() { + return feeds; + } + + public FilterValues severityLevels() { + return severityLevels; + } + + public FilterValues causes() { + return causes; + } + + public FilterValues effects() { + return effects; + } + + public FilterValues timePeriods() { + return timePeriods; + } + + @Override + public String toString() { + var builder = ToStringBuilder.ofEmbeddedType(); + if (!feeds.includeEverything()) { + builder.addCol("feeds", feeds.get()); + } + if (!severityLevels.includeEverything()) { + builder.addCol("severityLevels", severityLevels.get()); + } + if (!causes.includeEverything()) { + builder.addCol("causes", causes.get()); + } + if (!effects.includeEverything()) { + builder.addCol("effects", effects.get()); + } + if (!timePeriods.includeEverything()) { + builder.addCol("timePeriods", timePeriods.get()); + } + return builder.toString(); + } + + public static class Builder { + + @Nullable + private List feeds; + + @Nullable + private List severityLevels; + + @Nullable + private List causes; + + @Nullable + private List effects; + + @Nullable + private List timePeriods; + + public Builder withFeeds(@Nullable List feeds) { + this.feeds = feeds; + return this; + } + + public Builder withSeverityLevels(@Nullable List severityLevels) { + this.severityLevels = severityLevels; + return this; + } + + public Builder withCauses(@Nullable List causes) { + this.causes = causes; + return this; + } + + public Builder withEffects(@Nullable List effects) { + this.effects = effects; + return this; + } + + public Builder withTimePeriods(@Nullable List timePeriods) { + this.timePeriods = timePeriods; + return this; + } + + public TransitAlertSelectRequest build() { + return new TransitAlertSelectRequest(this); + } + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripMatcherFactory.java b/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripMatcherFactory.java index 44d0dbd60f8..84237367dce 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripMatcherFactory.java +++ b/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripMatcherFactory.java @@ -75,7 +75,7 @@ static Function> serviceDate( new ContainsMatcher<>( "serviceDate", t -> serviceDateProvider.apply(t.getServiceId()), - new EqualityMatcher<>("serviceDate", date, (dateToMatch -> dateToMatch)) + new EqualityMatcher<>("serviceDate", date, dateToMatch -> dateToMatch) ); } } diff --git a/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactory.java b/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactory.java index a9d1308e509..ed8be4e5bde 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactory.java +++ b/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactory.java @@ -1,9 +1,12 @@ package org.opentripplanner.transit.model.filter.transit; import java.time.LocalDate; +import java.util.Collection; import java.util.function.BiFunction; +import java.util.function.Function; import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.core.model.time.LocalDateRange; +import org.opentripplanner.core.model.time.TimePeriod; import org.opentripplanner.model.modes.AllowTransitModeFilter; import org.opentripplanner.transit.api.request.TripOnServiceDateRequest; import org.opentripplanner.transit.model.basic.NarrowedTransitMode; @@ -31,22 +34,26 @@ public class TripOnServiceDateMatcherFactory { /** * Creates a matcher for TripOnServiceDates. * - * @param request the criteria for filtering TripOnServiceDates. - * @param patternResolver resolves the pattern of a trip on a service date, or {@code null} if it - * has no pattern. + * @param request the criteria for filtering TripOnServiceDates. + * @param patternResolver resolves the pattern of a trip on a service date, or {@code null} if + * it has no pattern. + * @param runningTimeResolver resolves a trip's runtime according to its schedule, from the + * departure from the first stop to the arrival at the last stop. + * Returns {@code null} if the running time cannot be resolved, in + * which case the trip never matches a running time filter. * @return a matcher for filtering TripOnServiceDates. */ public static Matcher of( TripOnServiceDateRequest request, - BiFunction patternResolver + BiFunction patternResolver, + Function runningTimeResolver ) { ExpressionBuilder expr = ExpressionBuilder.of(); if (!request.filters().isEmpty()) { expr.matches( - SelectorBasedMatcherFactory.of( - request.filters(), - TripOnServiceDateMatcherFactory::buildSelectorMatcher + SelectorBasedMatcherFactory.of(request.filters(), selector -> + buildSelectorMatcher(selector, runningTimeResolver) ) ); } @@ -59,6 +66,11 @@ public static Matcher of( request.includeServiceDateRanges(), TripOnServiceDateMatcherFactory::serviceDateRange ); + if (!request.includeRunningTimePeriods().includeEverything()) { + expr.matches( + runningTimePeriods(request.includeRunningTimePeriods().get(), runningTimeResolver) + ); + } expr.atLeastOneMatch(request.includeAgencies(), TripOnServiceDateMatcherFactory::agencyId); expr.atLeastOneMatch(request.includeRoutes(), TripOnServiceDateMatcherFactory::routeId); expr.atLeastOneMatch(request.includePatterns(), id -> patternId(id, patternResolver)); @@ -85,7 +97,8 @@ public static Matcher of( * agencies, routes, and transport modes with AND logic. */ private static Matcher buildSelectorMatcher( - TripOnServiceDateSelectRequest selector + TripOnServiceDateSelectRequest selector, + Function runningTimeResolver ) { ExpressionBuilder expr = ExpressionBuilder.of(); @@ -95,6 +108,9 @@ private static Matcher buildSelectorMatcher( selector.serviceDateRanges(), TripOnServiceDateMatcherFactory::serviceDateRange ); + if (!selector.runningTimePeriods().includeEverything()) { + expr.matches(runningTimePeriods(selector.runningTimePeriods().get(), runningTimeResolver)); + } if (!selector.transportModes().includeEverything()) { var transportModeFilter = AllowTransitModeFilter.of( @@ -139,7 +155,7 @@ static Matcher replacementFor(FeedScopedId id) { return new ContainsMatcher<>( "replacementForContains", t -> t.getReplacementFor().stream().map(AbstractTransitEntity::getId).toList(), - new EqualityMatcher<>("replacementForIdEquals", id, (idToMatch -> idToMatch)) + new EqualityMatcher<>("replacementForIdEquals", id, idToMatch -> idToMatch) ); } @@ -159,6 +175,32 @@ static Matcher serviceDateRange(LocalDateRange dateRange) { ); } + /** + * Matches trips which are running during at least one of the given periods, according to their + * schedule. A trip is running from the scheduled departure from its first stop until the + * scheduled arrival at its last stop. Trips whose schedule cannot be resolved never match. + *

+ * The running time is resolved once per trip and then tested against every period, so that the + * (potentially expensive) {@code runningTimeResolver} is not invoked once per period. + */ + static Matcher runningTimePeriods( + Collection periods, + Function runningTimeResolver + ) { + return new GenericUnaryMatcher<>("runningTimePeriod", tripOnServiceDate -> { + var runningTime = runningTimeResolver.apply(tripOnServiceDate); + if (runningTime == null) { + return false; + } + for (var period : periods) { + if (period.overlaps(runningTime)) { + return true; + } + } + return false; + }); + } + static Matcher alteration(TripAlteration alteration) { return new EqualityMatcher<>("alteration", alteration, TripOnServiceDate::getTripAlteration); } diff --git a/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateSelectRequest.java b/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateSelectRequest.java index 268036a1a15..28f53285bb0 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateSelectRequest.java +++ b/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateSelectRequest.java @@ -4,6 +4,7 @@ import javax.annotation.Nullable; import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.core.model.time.LocalDateRange; +import org.opentripplanner.core.model.time.TimePeriod; import org.opentripplanner.transit.api.model.FilterValues; import org.opentripplanner.transit.model.basic.MainAndSubMode; import org.opentripplanner.utils.tostring.ToStringBuilder; @@ -20,6 +21,7 @@ public class TripOnServiceDateSelectRequest { private final FilterValues routes; private final FilterValues transportModes; private final FilterValues serviceDateRanges; + private final FilterValues runningTimePeriods; private TripOnServiceDateSelectRequest(Builder builder) { this.agencies = FilterValues.ofNullIsEverything("agencies", builder.agencies); @@ -29,6 +31,10 @@ private TripOnServiceDateSelectRequest(Builder builder) { "serviceDateRanges", builder.serviceDateRanges ); + this.runningTimePeriods = FilterValues.ofNullIsEverything( + "runningTimePeriods", + builder.runningTimePeriods + ); } public static Builder of() { @@ -51,6 +57,13 @@ public FilterValues serviceDateRanges() { return serviceDateRanges; } + /** + * Periods of time in which the entity must be running, according to its schedule. + */ + public FilterValues runningTimePeriods() { + return runningTimePeriods; + } + @Override public String toString() { var builder = ToStringBuilder.ofEmbeddedType(); @@ -66,6 +79,9 @@ public String toString() { if (!serviceDateRanges.includeEverything()) { builder.addCol("serviceDateRanges", serviceDateRanges.get()); } + if (!runningTimePeriods.includeEverything()) { + builder.addCol("runningTimePeriods", runningTimePeriods.get()); + } return builder.toString(); } @@ -83,6 +99,9 @@ public static class Builder { @Nullable private List serviceDateRanges; + @Nullable + private List runningTimePeriods; + public Builder withAgencies(List agencies) { this.agencies = agencies; return this; @@ -103,6 +122,11 @@ public Builder withServiceDateRanges(List serviceDateRanges) { return this; } + public Builder withRunningTimePeriods(List runningTimePeriods) { + this.runningTimePeriods = runningTimePeriods; + return this; + } + public TripOnServiceDateSelectRequest build() { return new TripOnServiceDateSelectRequest(this); } diff --git a/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripTimeOnDateMatcherFactory.java b/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripTimeOnDateMatcherFactory.java index f1f7fa4d566..79ea07dbecd 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripTimeOnDateMatcherFactory.java +++ b/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripTimeOnDateMatcherFactory.java @@ -1,6 +1,8 @@ package org.opentripplanner.transit.model.filter.transit; +import java.time.Instant; import org.opentripplanner.core.model.id.FeedScopedId; +import org.opentripplanner.core.model.time.TimePeriod; import org.opentripplanner.model.TripTimeOnDate; import org.opentripplanner.model.modes.AllowTransitModeFilter; import org.opentripplanner.transit.api.request.TripTimeOnDateRequest; @@ -41,6 +43,10 @@ public static Matcher of(TripTimeOnDateRequest request) { expr.atLeastOneMatch(request.includeAgencies(), TripTimeOnDateMatcherFactory::agencyId); expr.atLeastOneMatch(request.includeRoutes(), TripTimeOnDateMatcherFactory::routeId); expr.atLeastOneMatch(request.includeModes(), TripTimeOnDateMatcherFactory::mode); + expr.atLeastOneMatch( + request.includeCallTimePeriods(), + TripTimeOnDateMatcherFactory::callTimePeriod + ); expr.matchesNone(request.excludeAgencies(), TripTimeOnDateMatcherFactory::agencyId); expr.matchesNone(request.excludeRoutes(), TripTimeOnDateMatcherFactory::routeId); expr.matchesNone(request.excludeModes(), TripTimeOnDateMatcherFactory::mode); @@ -94,4 +100,33 @@ private static Matcher routeId(FeedScopedId id) { private static Matcher mode(TransitMode mode) { return new EqualityMatcher<>("mode", mode, t -> t.getTrip().getMode()); } + + /** + * Matches calls where the vehicle is scheduled to visit the stop during the given period. The + * visit lasts from the scheduled arrival at the stop until the scheduled departure from it, and + * the period is half-open, meaning that its end is exclusive. Calls without scheduled times, for + * example flexible ones, never match. + */ + private static Matcher callTimePeriod(TimePeriod period) { + return new GenericUnaryMatcher<>("callTimePeriod", call -> { + if (call.getServiceDayMidnight() == TripTimeOnDate.UNDEFINED || !call.hasScheduledTimes()) { + return false; + } + return visitOverlaps(period, call.scheduledArrival(), call.scheduledDeparture()); + }); + } + + /** + * Returns {@code true} if the visit at the stop, lasting from {@code arrival} to + * {@code departure} (both inclusive), overlaps the given period. A visit which lasts no time at + * all matches if the period contains the instant of the visit. + */ + private static boolean visitOverlaps(TimePeriod period, Instant arrival, Instant departure) { + boolean afterStart = period + .start() + .map(start -> !departure.isBefore(start)) + .orElse(true); + boolean beforeEnd = period.end().map(arrival::isBefore).orElse(true); + return afterStart && beforeEnd; + } } diff --git a/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractBuilder.java index b1b490f6830..e214060971f 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractBuilder.java @@ -5,8 +5,7 @@ public abstract class AbstractBuilder< E extends TransitObject, B extends AbstractBuilder -> - implements TransitBuilder { +> implements TransitBuilder { private final E original; diff --git a/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractEntityBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractEntityBuilder.java index 07fb600b830..313d3742ce2 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractEntityBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractEntityBuilder.java @@ -4,11 +4,12 @@ import org.opentripplanner.core.model.id.FeedScopedId; public abstract class AbstractEntityBuilder< - E extends AbstractTransitEntity, - B extends AbstractEntityBuilder -> + E extends AbstractTransitEntity, + B extends AbstractEntityBuilder + > extends AbstractBuilder - implements TransitEntityBuilder { + implements TransitEntityBuilder +{ @SuppressWarnings("rawtypes") private static final EntityContext NOOP = new EntityContext() {}; diff --git a/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java b/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java index 4c1225df469..41e5fadf4f4 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java +++ b/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java @@ -23,8 +23,7 @@ public abstract class AbstractTransitEntity< E extends AbstractTransitEntity, B extends AbstractEntityBuilder -> - implements TransitEntity, TransitObject, Serializable { +> implements TransitEntity, TransitObject, Serializable { private final FeedScopedId id; @@ -64,7 +63,7 @@ public final String toString() { buf.append('{').append(getId()); - if ((this instanceof LogInfo n) && n.logName() != null) { + if (this instanceof LogInfo n && n.logName() != null) { buf.append(' ').append(n.logName()); } buf.append('}'); diff --git a/application/src/main/java/org/opentripplanner/transit/model/framework/DefaultEntityContext.java b/application/src/main/java/org/opentripplanner/transit/model/framework/DefaultEntityContext.java index 7c4d771d5a4..927282aeeb9 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/framework/DefaultEntityContext.java +++ b/application/src/main/java/org/opentripplanner/transit/model/framework/DefaultEntityContext.java @@ -3,8 +3,7 @@ public class DefaultEntityContext< E extends AbstractTransitEntity, B extends AbstractEntityBuilder -> - implements EntityContext { +> implements EntityContext { private final EntityById target; diff --git a/application/src/main/java/org/opentripplanner/transit/model/framework/TransitEntityBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/framework/TransitEntityBuilder.java index 843d478c9e5..47554a377a1 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/framework/TransitEntityBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/framework/TransitEntityBuilder.java @@ -3,8 +3,7 @@ public interface TransitEntityBuilder< E extends TransitObject, B extends TransitEntityBuilder -> - extends TransitBuilder { +> extends TransitBuilder { /** * Create a new {@link TransitObject} instance from the builder values and store the object in * the current context. This change will propagate to the master service/index when the diff --git a/application/src/main/java/org/opentripplanner/transit/model/framework/TransitObject.java b/application/src/main/java/org/opentripplanner/transit/model/framework/TransitObject.java index 60d261fee00..8927e26bd54 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/framework/TransitObject.java +++ b/application/src/main/java/org/opentripplanner/transit/model/framework/TransitObject.java @@ -2,8 +2,10 @@ import java.io.Serializable; -public interface TransitObject, T extends TransitBuilder> - extends Serializable { +public interface TransitObject< + E extends TransitObject, + T extends TransitBuilder +> extends Serializable { /** * Return {@code true} if this is the same as the given other objects, all fields must have * the same value. This is used to avoid creating new objects during transit model construction diff --git a/application/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutes.java b/application/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutes.java index f55c121437e..0a5b918f437 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutes.java +++ b/application/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutes.java @@ -13,7 +13,8 @@ */ public class GroupOfRoutes extends AbstractTransitEntity - implements LogInfo { + implements LogInfo +{ private final String name; private final String privateCode; diff --git a/application/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutesBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutesBuilder.java index 19a82533add..f5bc66f42c5 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutesBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutesBuilder.java @@ -9,7 +9,8 @@ * example divide lines into commercial and non-commercial groups. */ public class GroupOfRoutesBuilder - extends AbstractEntityBuilder { + extends AbstractEntityBuilder +{ private String privateCode; private String shortName; diff --git a/application/src/main/java/org/opentripplanner/transit/model/network/TripPattern.java b/application/src/main/java/org/opentripplanner/transit/model/network/TripPattern.java index ba5cdaadb84..fb27ac4dd80 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/network/TripPattern.java +++ b/application/src/main/java/org/opentripplanner/transit/model/network/TripPattern.java @@ -60,7 +60,8 @@ */ public final class TripPattern extends AbstractTransitEntity - implements Cloneable, LogInfo { + implements Cloneable, LogInfo +{ private final Route route; @@ -349,7 +350,7 @@ public boolean alightingExist(StopLocation stop) { /** Returns whether a given stop is wheelchair-accessible. */ public boolean wheelchairAccessible(int stopPos) { - return (stopPattern.getStop(stopPos).getWheelchairAccessibility() == Accessibility.POSSIBLE); + return stopPattern.getStop(stopPos).getWheelchairAccessibility() == Accessibility.POSSIBLE; } public PickDrop getAlightType(int stopPos) { diff --git a/application/src/main/java/org/opentripplanner/transit/model/network/TripPatternBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/network/TripPatternBuilder.java index ab56736416f..5d5f9426aef 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/network/TripPatternBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/network/TripPatternBuilder.java @@ -21,7 +21,8 @@ @SuppressWarnings("UnusedReturnValue") public final class TripPatternBuilder - extends AbstractEntityBuilder { + extends AbstractEntityBuilder +{ private String name; private boolean realTimeTripPattern; @@ -303,9 +304,8 @@ private List generateHopGeometriesFromOriginalTripPattern() { List hopGeometries = new ArrayList<>(); for (int i = 0; i < stopPattern.getSize() - 1; i++) { - LineString hopGeometry = i < originalTripPattern.numberOfStops() - 1 - ? originalTripPattern.getHopGeometry(i) - : null; + LineString hopGeometry = + i < originalTripPattern.numberOfStops() - 1 ? originalTripPattern.getHopGeometry(i) : null; if (hopGeometry != null && stopPattern.sameStops(originalTripPattern.getStopPattern(), i)) { // Copy hop geometry from previous pattern @@ -315,7 +315,10 @@ private List generateHopGeometriesFromOriginalTripPattern() { ) { // Use old geometry but patch first and last point with new stops var newStart = stopPattern.getStop(i).getCoordinate().asJtsCoordinate(); - var newEnd = stopPattern.getStop(i + 1).getCoordinate().asJtsCoordinate(); + var newEnd = stopPattern + .getStop(i + 1) + .getCoordinate() + .asJtsCoordinate(); Coordinate[] coordinates = originalTripPattern.getHopGeometry(i).getCoordinates().clone(); coordinates[0].setCoordinate(newStart); @@ -325,12 +328,13 @@ private List generateHopGeometriesFromOriginalTripPattern() { } else { // Create new straight-line geometry for hop hopGeometries.add( - GeometryUtils.getGeometryFactory().createLineString( - new Coordinate[] { - stopPattern.getStop(i).getCoordinate().asJtsCoordinate(), - stopPattern.getStop(i + 1).getCoordinate().asJtsCoordinate(), - } - ) + GeometryUtils.getGeometryFactory().createLineString(new Coordinate[] { + stopPattern.getStop(i).getCoordinate().asJtsCoordinate(), + stopPattern + .getStop(i + 1) + .getCoordinate() + .asJtsCoordinate(), + }) ); } } diff --git a/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/DefaultTransitGroupPriorityCalculator.java b/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/DefaultTransitGroupPriorityCalculator.java index 3e96cf18f95..5404928ba1c 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/DefaultTransitGroupPriorityCalculator.java +++ b/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/DefaultTransitGroupPriorityCalculator.java @@ -7,7 +7,8 @@ * Implement {@link RaptorTransitGroupPriorityCalculator}. */ public final class DefaultTransitGroupPriorityCalculator - implements RaptorTransitGroupPriorityCalculator { + implements RaptorTransitGroupPriorityCalculator +{ @Override public int mergeInGroupId(int currentGroupIds, int boardingGroupId) { diff --git a/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/Matchers.java b/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/Matchers.java index 9e7baf99ead..f73edd4df8f 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/Matchers.java +++ b/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/Matchers.java @@ -72,7 +72,10 @@ private static String arrayToString(BinarySetOperator op, T[] values) { } private static String colToString(BinarySetOperator op, Collection values) { - return values.stream().map(Objects::toString).collect(Collectors.joining(" " + op + " ")); + return values + .stream() + .map(Objects::toString) + .collect(Collectors.joining(" " + op + " ")); } private static Matcher andOf(List list) { @@ -138,7 +141,10 @@ public RegExpMatcher( Function toValue ) { this.typeName = typeName; - this.patterns = regexps.stream().map(Pattern::compile).toArray(Pattern[]::new); + this.patterns = regexps + .stream() + .map(Pattern::compile) + .toArray(Pattern[]::new); this.matchers = Arrays.stream(this.patterns) .map(p -> p.matcher("")) .toArray(java.util.regex.Matcher[]::new); diff --git a/application/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java b/application/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java index e6d2dcb3e95..dd1cd956d2f 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java @@ -19,7 +19,8 @@ public class AreaStop extends AbstractTransitEntity - implements StopLocation { + implements StopLocation +{ private final int index; private final I18NString name; diff --git a/application/src/main/java/org/opentripplanner/transit/model/site/BoardingAreaBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/site/BoardingAreaBuilder.java index c85dd2d3da5..dff9ff8eeaf 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/site/BoardingAreaBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/BoardingAreaBuilder.java @@ -4,7 +4,8 @@ import org.opentripplanner.core.model.id.FeedScopedId; public final class BoardingAreaBuilder - extends StationElementBuilder { + extends StationElementBuilder +{ private RegularStop parentStop; diff --git a/application/src/main/java/org/opentripplanner/transit/model/site/GroupOfStations.java b/application/src/main/java/org/opentripplanner/transit/model/site/GroupOfStations.java index 7c68f4414a2..9bfb14583e8 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/site/GroupOfStations.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/GroupOfStations.java @@ -16,7 +16,8 @@ */ public class GroupOfStations extends AbstractTransitEntity - implements StopLocationsGroup { + implements StopLocationsGroup +{ private final Set childStations; private final I18NString name; @@ -50,7 +51,8 @@ public WgsCoordinate getCoordinate() { } public Collection getChildStops() { - return this.childStations.stream() + return this.childStations + .stream() .flatMap(s -> s.getChildStops().stream()) .toList(); } diff --git a/application/src/main/java/org/opentripplanner/transit/model/site/GroupOfStationsBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/site/GroupOfStationsBuilder.java index 26c78069090..bec295b3098 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/site/GroupOfStationsBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/GroupOfStationsBuilder.java @@ -8,7 +8,8 @@ import org.opentripplanner.transit.model.framework.AbstractEntityBuilder; public class GroupOfStationsBuilder - extends AbstractEntityBuilder { + extends AbstractEntityBuilder +{ private I18NString name; private Set childStations = new HashSet<>(); diff --git a/application/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java b/application/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java index c712b657fa8..0d3faeea966 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java @@ -17,7 +17,8 @@ */ public class GroupStop extends AbstractTransitEntity - implements StopLocation { + implements StopLocation +{ private final int index; private final List stopLocations; diff --git a/application/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java index e8216ef4d21..6287cdd3c1b 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java @@ -67,8 +67,10 @@ public I18NString name() { public GroupStopBuilder addLocation(StopLocation location) { if ( - !(location.getStopType() == StopType.REGULAR || - location.getStopType() == StopType.FLEXIBLE_AREA) + !( + location.getStopType() == StopType.REGULAR || + location.getStopType() == StopType.FLEXIBLE_AREA + ) ) { throw new RuntimeException( String.format( diff --git a/application/src/main/java/org/opentripplanner/transit/model/site/MultiModalStation.java b/application/src/main/java/org/opentripplanner/transit/model/site/MultiModalStation.java index 50aac509bf3..d882f9026e2 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/site/MultiModalStation.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/MultiModalStation.java @@ -15,7 +15,8 @@ */ public class MultiModalStation extends AbstractTransitEntity - implements StopLocationsGroup { + implements StopLocationsGroup +{ private final Collection childStations; @@ -59,7 +60,8 @@ public Collection getChildStations() { } public Collection getChildStops() { - return this.childStations.stream() + return this.childStations + .stream() .flatMap(s -> s.getChildStops().stream()) .toList(); } diff --git a/application/src/main/java/org/opentripplanner/transit/model/site/MultiModalStationBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/site/MultiModalStationBuilder.java index f4e9c1b4076..59648cf7c80 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/site/MultiModalStationBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/MultiModalStationBuilder.java @@ -8,7 +8,8 @@ import org.opentripplanner.transit.model.framework.AbstractEntityBuilder; public class MultiModalStationBuilder - extends AbstractEntityBuilder { + extends AbstractEntityBuilder +{ private Collection childStations; diff --git a/application/src/main/java/org/opentripplanner/transit/model/site/PathwayNodeBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/site/PathwayNodeBuilder.java index bab3be004d6..fcdb9b4fb73 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/site/PathwayNodeBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/PathwayNodeBuilder.java @@ -6,7 +6,8 @@ * A place where a station connects to the street network. Equivalent to GTFS stop location . */ public final class PathwayNodeBuilder - extends StationElementBuilder { + extends StationElementBuilder +{ PathwayNodeBuilder(FeedScopedId id) { super(id); diff --git a/application/src/main/java/org/opentripplanner/transit/model/site/RegularStop.java b/application/src/main/java/org/opentripplanner/transit/model/site/RegularStop.java index 954d072f70a..e9e47f99dab 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/site/RegularStop.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/RegularStop.java @@ -23,7 +23,8 @@ */ public final class RegularStop extends StationElement - implements StopLocation { + implements StopLocation +{ private final int index; private final String platformCode; diff --git a/application/src/main/java/org/opentripplanner/transit/model/site/RegularStopBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/site/RegularStopBuilder.java index c7acc8a03c4..bcbad0adeed 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/site/RegularStopBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/RegularStopBuilder.java @@ -19,7 +19,8 @@ * platform at a train station. Equivalent to GTFS stop location 0 or NeTEx quay. */ public final class RegularStopBuilder - extends StationElementBuilder { + extends StationElementBuilder +{ private final IntSupplier indexCounter; diff --git a/application/src/main/java/org/opentripplanner/transit/model/site/Station.java b/application/src/main/java/org/opentripplanner/transit/model/site/Station.java index 9de9ae10569..29d87844acd 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/site/Station.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/Station.java @@ -27,7 +27,8 @@ */ public class Station extends AbstractTransitEntity - implements StopLocationsGroup, LogInfo { + implements StopLocationsGroup, LogInfo +{ private final I18NString name; private final String code; @@ -209,9 +210,10 @@ private static GeometryCollection computeGeometry( ); var convexHull = new ConvexHull(geometryCollection).getConvexHull(); - var geometries = stationPoint != null - ? new Geometry[] { stationPoint, convexHull } - : new Geometry[] { convexHull }; + var geometries = + stationPoint != null + ? new Geometry[] { stationPoint, convexHull } + : new Geometry[] { convexHull }; return getGeometryFactory().createGeometryCollection(geometries); } } diff --git a/application/src/main/java/org/opentripplanner/transit/model/site/StationElement.java b/application/src/main/java/org/opentripplanner/transit/model/site/StationElement.java index b5e758b573a..560d04fc9b6 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/site/StationElement.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/StationElement.java @@ -17,8 +17,7 @@ public abstract class StationElement< E extends StationElement, B extends StationElementBuilder -> - extends AbstractTransitEntity { +> extends AbstractTransitEntity { private final I18NString name; diff --git a/application/src/main/java/org/opentripplanner/transit/model/site/StationElementBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/site/StationElementBuilder.java index 4980109d275..95aa9351d0a 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/site/StationElementBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/StationElementBuilder.java @@ -15,8 +15,7 @@ public abstract class StationElementBuilder< E extends StationElement, B extends StationElementBuilder -> - extends AbstractEntityBuilder { +> extends AbstractEntityBuilder { private I18NString name; private String code; diff --git a/application/src/main/java/org/opentripplanner/transit/model/timetable/EstimatedTime.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/EstimatedTime.java index 359a8c7de6a..7981bd272fe 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/timetable/EstimatedTime.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/EstimatedTime.java @@ -23,7 +23,7 @@ private EstimatedTime(ZonedDateTime time, Duration delay) { public static EstimatedTime of(ZonedDateTime scheduledTime, int delaySecs) { var delay = Duration.ofSeconds(delaySecs); - return new EstimatedTime(scheduledTime.minus(delay), delay); + return new EstimatedTime(scheduledTime.plus(delay), delay); } public ZonedDateTime time() { diff --git a/application/src/main/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimes.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimes.java index 55d9f29b559..54156131249 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimes.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimes.java @@ -238,7 +238,7 @@ public boolean isExtraCall(int stopPos) { @Override public boolean isRealTimeUpdated(int stopPos) { - return (state.hasAnyUpdates() && !isStopRealTimeStates(stopPos, StopRealTimeState.NO_DATA)); + return state.hasAnyUpdates() && !isStopRealTimeStates(stopPos, StopRealTimeState.NO_DATA); } /** diff --git a/application/src/main/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimesBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimesBuilder.java index 16c20bb5ff7..442857803f0 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimesBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimesBuilder.java @@ -304,8 +304,8 @@ public RealTimeTripTimesBuilder withTripHeadsign(I18NString headsign) { } public @Nullable I18NString[] stopHeadsigns() { - var result = scheduledTripTimes.copyHeadsigns(() -> - new I18NString[scheduledTripTimes.getNumStops()] + var result = scheduledTripTimes.copyHeadsigns( + () -> new I18NString[scheduledTripTimes.getNumStops()] ); for (var i = 0; i < result.length; i++) { if (stopHeadsigns[i] != null) { diff --git a/application/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimes.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimes.java index 6d72c7b9d5f..17a335f2fa6 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimes.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimes.java @@ -134,7 +134,9 @@ public RealTimeTripTimesBuilder createRealTimeFromScheduledTimes() { @Override public ScheduledTripTimes withAdjustedTimes(Duration shiftDelta) { - return copyOfNoDuplication().plusTimeShift((int) shiftDelta.toSeconds()).build(); + return copyOfNoDuplication() + .plusTimeShift((int) shiftDelta.toSeconds()) + .build(); } @Override @@ -275,7 +277,7 @@ public I18NString getTripHeadsign() { @Override @Nullable public I18NString getHeadsign(final int stopPos) { - return (headsigns != null && headsigns[stopPos] != null) + return headsigns != null && headsigns[stopPos] != null ? headsigns[stopPos] : getTrip().getHeadsign(); } diff --git a/application/src/main/java/org/opentripplanner/transit/model/timetable/StopTimeToScheduledTripTimesMapper.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/StopTimeToScheduledTripTimesMapper.java index 6e6a489ef2c..a6d5e85555d 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/timetable/StopTimeToScheduledTripTimesMapper.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/StopTimeToScheduledTripTimesMapper.java @@ -79,7 +79,7 @@ private I18NString[] makeHeadsignsArray(final Collection stopTimes) { useStopHeadsigns = true; } else { for (final StopTime st : stopTimes) { - if (!(tripHeadsign.equals(st.getStopHeadsign()))) { + if (!tripHeadsign.equals(st.getStopHeadsign())) { useStopHeadsigns = true; break; } diff --git a/application/src/main/java/org/opentripplanner/transit/model/timetable/TimetableValidationError.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/TimetableValidationError.java index 8c3418070eb..1652825eb09 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/timetable/TimetableValidationError.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/TimetableValidationError.java @@ -5,8 +5,11 @@ /** * Details about why a {@link TripTimes} instance is invalid. */ -public record TimetableValidationError(ErrorCode code, int stopIndex, Trip trip) implements - OtpError { +public record TimetableValidationError( + ErrorCode code, + int stopIndex, + Trip trip +) implements OtpError { @Override public String errorCode() { return code.name(); diff --git a/application/src/main/java/org/opentripplanner/transit/model/timetable/Trip.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/Trip.java index 109054db02b..8dee9b675fb 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/timetable/Trip.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/Trip.java @@ -72,9 +72,10 @@ public final class Trip extends AbstractTransitEntity impleme // Route is done first, it is used as a fallback for some fields this.route = requireNonNull(builder.getRoute()); this.mode = requireNonNullElse(builder.getMode(), route.getMode()); - this.netexSubmode = builder.getNetexSubmode() != null - ? SubMode.getOrBuildAndCacheForever(builder.getNetexSubmode()) - : route.getNetexSubmode(); + this.netexSubmode = + builder.getNetexSubmode() != null + ? SubMode.getOrBuildAndCacheForever(builder.getNetexSubmode()) + : route.getNetexSubmode(); this.direction = requireNonNullElse(builder.getDirection(), Direction.UNKNOWN); this.bikesAllowed = requireNonNullElse(builder.getBikesAllowed(), route.getBikesAllowed()); this.carsAllowed = requireNonNullElse(builder.getCarsAllowed(), CarAccess.UNKNOWN); diff --git a/application/src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDate.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDate.java index 9cc8178d6a9..974f29e4e05 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDate.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDate.java @@ -11,7 +11,8 @@ * or an instance of a generic trip on a certain service date. */ public class TripOnServiceDate - extends AbstractTransitEntity { + extends AbstractTransitEntity +{ private final Trip trip; private final LocalDate serviceDate; diff --git a/application/src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDateBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDateBuilder.java index 8b77bb2a325..705a6b1ab04 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDateBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDateBuilder.java @@ -7,7 +7,8 @@ import org.opentripplanner.transit.model.framework.AbstractEntityBuilder; public class TripOnServiceDateBuilder - extends AbstractEntityBuilder { + extends AbstractEntityBuilder +{ private Trip trip; private LocalDate serviceDate; diff --git a/application/src/main/java/org/opentripplanner/transit/model/timetable/TripTimes.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripTimes.java index 81b4d5e87ad..58e226c2ca7 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/timetable/TripTimes.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripTimes.java @@ -5,12 +5,15 @@ import java.io.Serializable; import java.time.Duration; +import java.time.Instant; import java.util.Comparator; import java.util.List; import java.util.OptionalInt; import javax.annotation.Nullable; import org.opentripplanner.core.model.accessibility.Accessibility; import org.opentripplanner.core.model.i18n.I18NString; +import org.opentripplanner.core.model.time.TimePeriod; +import org.opentripplanner.model.StopTime; import org.opentripplanner.transit.model.framework.DataValidationException; import org.opentripplanner.transit.model.network.ReplacedByRelation; import org.opentripplanner.transit.model.timetable.booking.BookingInfo; @@ -28,7 +31,8 @@ */ public sealed interface TripTimes extends Serializable, Comparable - permits RealTimeTripTimes, ScheduledTripTimes { + permits RealTimeTripTimes, ScheduledTripTimes +{ /** * Create a RealTimeTripTimesBuilder using the information, but not the times, from this * TripTimes. @@ -197,6 +201,39 @@ default int compareTo(TripTimes other) { int getNumStops(); + /** + * resolves a trip's runtime on a service day, according to its schedule. The period starts at the + * scheduled departure from the first stop and ends at the scheduled arrival at the last stop. + *

+ * + * @param startOfService the start of the service day the trip is running on, see + * {@link + * org.opentripplanner.utils.time.ServiceDateUtils#asStartOfService}. + * @return {@code null} if the schedule of the trip cannot be resolved, either because the trip + * has no stops or because the departure from the first stop or the arrival at the last stop is + * missing or inconsistent. + */ + @Nullable + default TimePeriod scheduledRunningTime(Instant startOfService) { + int numStops = getNumStops(); + if (numStops == 0) { + return null; + } + int departure = getScheduledDepartureTime(0); + int arrival = getScheduledArrivalTime(numStops - 1); + if ( + departure == StopTime.MISSING_VALUE || + arrival == StopTime.MISSING_VALUE || + departure > arrival + ) { + return null; + } + return TimePeriod.of( + startOfService.plusSeconds(departure), + startOfService.plusSeconds(arrival) + ); + } + /** * When creating trip times, or wrapping them in updates, we could potentially imply negative * running or dwell times. We really don't want those being used in routing. This method checks diff --git a/application/src/main/java/org/opentripplanner/transit/model/timetable/booking/RoutingBookingInfo.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/booking/RoutingBookingInfo.java index 8a6367f2035..86b145b21ba 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/timetable/booking/RoutingBookingInfo.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/booking/RoutingBookingInfo.java @@ -155,16 +155,14 @@ Builder withBookingInfo(@Nullable BookingInfo bookingInfo) { } public Builder withLatestBookingTime(@Nullable BookingTime latestBookingTime) { - this.latestBookingTime = latestBookingTime == null - ? NOT_SET - : latestBookingTime.relativeTimeSeconds(); + this.latestBookingTime = + latestBookingTime == null ? NOT_SET : latestBookingTime.relativeTimeSeconds(); return this; } public Builder withMinimumBookingNotice(@Nullable Duration minimumBookingNotice) { - this.minimumBookingNotice = minimumBookingNotice == null - ? NOT_SET - : (int) minimumBookingNotice.toSeconds(); + this.minimumBookingNotice = + minimumBookingNotice == null ? NOT_SET : (int) minimumBookingNotice.toSeconds(); return this; } diff --git a/application/src/main/java/org/opentripplanner/transit/repository/DefaultTimetableRepository.java b/application/src/main/java/org/opentripplanner/transit/repository/DefaultTimetableRepository.java index b29b3c356c1..a35e33863b3 100644 --- a/application/src/main/java/org/opentripplanner/transit/repository/DefaultTimetableRepository.java +++ b/application/src/main/java/org/opentripplanner/transit/repository/DefaultTimetableRepository.java @@ -31,7 +31,7 @@ import org.opentripplanner.routing.algorithm.raptoradapter.transit.RaptorTransitData; import org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers.TimetableUpdateMapper; import org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers.TripPatternForDateMapper; -import org.opentripplanner.transit.model.calendar.DefaultTripCalendars; +import org.opentripplanner.transit.model.calendar.TripCalendars; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.StopLocation; @@ -161,7 +161,16 @@ public class DefaultTimetableRepository implements TimetableRepository { TripIdAndServiceDate, TripOnServiceDate > realTimeAddedTripOnServiceDateForTripAndDay; - private final DefaultTripCalendars tripCalendars; + + /** + * The trip calendar. Since {@link TripCalendars} is immutable, the mutable (not + * {@link #readOnly}) instance and the frozen snapshot produced by {@link #createSnapshot()} can + * safely share the exact same value: the mutable instance's calls to + * {@link #getOrCreateServiceIdForDate} simply reassign this field to a new value, never touching + * the one the snapshot captured. + */ + private TripCalendars tripCalendars; + private RaptorTransitData realtimeRaptorTransitData; /** @@ -184,7 +193,7 @@ public class DefaultTimetableRepository implements TimetableRepository { public DefaultTimetableRepository( RaptorTransitData raptorTransitData, - DefaultTripCalendars tripCalendars + TripCalendars tripCalendars ) { this( new HashMap<>(), @@ -215,7 +224,7 @@ public DefaultTimetableRepository( ListMultimap realTimeAddedReplacedByTripOnServiceDateById, Map realTimeAddedTripOnServiceDateForTripAndDay, SetMultimap patternsForStop, - DefaultTripCalendars tripCalendars, + TripCalendars tripCalendars, RaptorTransitData realtimeRaptorTransitData, boolean readOnly, TimetableUpdateMapper timetableUpdateMapper @@ -634,6 +643,25 @@ public RaptorTransitData getRealtimeRaptorTransitData() { return realtimeRaptorTransitData; } + @Override + public TripCalendars getTripCalendars() { + return tripCalendars; + } + + /** + * Creates the new service id directly on this mutable write buffer's trip calendar, so that it + * is visible to (and only to) this write transaction until it commits. + */ + @Override + @Nullable + public FeedScopedId getOrCreateServiceIdForDate(LocalDate serviceDate) { + validateNotReadOnly(); + return tripCalendars.getOrCreateServiceIdForDate( + serviceDate, + updated -> this.tripCalendars = updated + ); + } + /** * Clear timetable for all patterns matching the provided feed id. * @@ -785,15 +813,13 @@ private List findTripsOnServiceDates(Predicate fil .values() .stream() .flatMap(timetables -> - timetables - .stream() - .flatMap(timetable -> - timetable - .getTripTimes() - .stream() - .filter(filter) - .map(tripTimes -> mapToTripOnServiceDate(tripTimes, timetable)) - ) + timetables.stream().flatMap(timetable -> + timetable + .getTripTimes() + .stream() + .filter(filter) + .map(tripTimes -> mapToTripOnServiceDate(tripTimes, timetable)) + ) ) .collect(Collectors.toCollection(ArrayList::new)); } diff --git a/application/src/main/java/org/opentripplanner/transit/repository/TimetableRepository.java b/application/src/main/java/org/opentripplanner/transit/repository/TimetableRepository.java index 5fa6fabe97f..0ffdb5b4e93 100644 --- a/application/src/main/java/org/opentripplanner/transit/repository/TimetableRepository.java +++ b/application/src/main/java/org/opentripplanner/transit/repository/TimetableRepository.java @@ -1,12 +1,13 @@ package org.opentripplanner.transit.repository; import java.time.LocalDate; +import javax.annotation.Nullable; import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.transit.model.timetable.RealTimeTripUpdate; /** - * The mutable repository for the realtime-updated timetables. It is managed by the transaction - * framework: trip updaters obtain it through a + * The mutable repository for the realtime-updated timetables and trip calendar. It is managed by + * the transaction framework: trip updaters obtain it through a * {@link org.opentripplanner.framework.transaction.api.WriteContext} on the single writer thread, * and {@link #createSnapshot()} is called at commit time to publish a new immutable * {@link TimetableRepositorySnapshot} for the request threads. @@ -20,6 +21,17 @@ public interface TimetableRepository extends TimetableRepositorySnapshot { */ void update(RealTimeTripUpdate realTimeTripUpdate); + /** + * Get or create a serviceId for a given date. Used when a new trip is added from a realtime + * data update. It makes sure the date is in the existing transit service period. + * + * @param serviceDate service date for the added service id + * @return service-id for date if it exists or is created. If the given service date is outside + * the service period {@code null} is returned. + */ + @Nullable + FeedScopedId getOrCreateServiceIdForDate(LocalDate serviceDate); + /** * Produce an immutable snapshot of the current state of this repository. */ diff --git a/application/src/main/java/org/opentripplanner/transit/repository/TimetableRepositoryLifecycle.java b/application/src/main/java/org/opentripplanner/transit/repository/TimetableRepositoryLifecycle.java index 6bd272fac6d..44e6c905553 100644 --- a/application/src/main/java/org/opentripplanner/transit/repository/TimetableRepositoryLifecycle.java +++ b/application/src/main/java/org/opentripplanner/transit/repository/TimetableRepositoryLifecycle.java @@ -11,7 +11,8 @@ * purging expired data). */ public class TimetableRepositoryLifecycle - implements RepositoryLifecycle { + implements RepositoryLifecycle +{ private final TimetableRepository buffer; private final boolean purgeExpiredData; diff --git a/application/src/main/java/org/opentripplanner/transit/repository/TimetableRepositorySnapshot.java b/application/src/main/java/org/opentripplanner/transit/repository/TimetableRepositorySnapshot.java index 60123c659ee..3a9b8a084d1 100644 --- a/application/src/main/java/org/opentripplanner/transit/repository/TimetableRepositorySnapshot.java +++ b/application/src/main/java/org/opentripplanner/transit/repository/TimetableRepositorySnapshot.java @@ -6,6 +6,7 @@ import javax.annotation.Nullable; import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.routing.algorithm.raptoradapter.transit.RaptorTransitData; +import org.opentripplanner.transit.model.calendar.TripCalendars; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.StopLocation; @@ -15,10 +16,14 @@ import org.opentripplanner.transit.model.timetable.TripOnServiceDate; /** - * An immutable, read-only snapshot of the realtime-updated timetables. A new snapshot is published - * each time a transaction that touched the {@link TimetableRepository} commits. Request - * threads read a snapshot resolved at the start of the request, through the request-scoped - * {@link org.opentripplanner.transit.service.TransitService}. + * An immutable, read-only snapshot of the realtime-updated timetables and trip calendar. A new + * snapshot is published each time a transaction that touched the {@link TimetableRepository} + * commits. Request threads read a snapshot resolved at the start of the request, through the + * request-scoped {@link org.opentripplanner.transit.service.TransitService}. + *

+ * The trip calendar is included here (rather than being its own repository) because every + * consumer that needs realtime timetable data also needs the calendar — new service ids created + * for real-time-added trips must be visible in the same transaction as the trips that use them. */ public interface TimetableRepositorySnapshot { /** @@ -126,4 +131,10 @@ TripOnServiceDate getRealTimeAddedTripOnServiceDateForTripAndDay( * Does this snapshot contain any realtime data or is it completely empty? */ boolean isEmpty(); + + /** + * Return the trip calendar for this snapshot, including any service ids created for + * real-time-added trips. + */ + TripCalendars getTripCalendars(); } diff --git a/application/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java b/application/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java index aa5b8eb103a..c45c3d1b146 100644 --- a/application/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java +++ b/application/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java @@ -23,6 +23,7 @@ import javax.annotation.Nullable; import org.locationtech.jts.geom.Envelope; import org.opentripplanner.core.model.id.FeedScopedId; +import org.opentripplanner.core.model.time.TimePeriod; import org.opentripplanner.ext.flex.FlexIndex; import org.opentripplanner.framework.application.OTPRequestTimeoutException; import org.opentripplanner.model.FeedInfo; @@ -101,8 +102,7 @@ public class DefaultTransitService implements TransitService { /** * Create a service without a real-time snapshot (and therefore without any real-time data). - * This is the constructor used by Dagger injection. Use the {@link TransitService} via the - * {@link org.opentripplanner.standalone.api.OtpServerRequestContext} if real-time data is needed. + * This is the constructor used by Dagger injection. */ @Inject public DefaultTransitService(TransitRepository transitRepository) { @@ -212,7 +212,7 @@ public Collection listStations() { @Override public TIntSet getServiceCodesRunningForDate(LocalDate serviceDate) { - return transitRepository + return getTripCalendars() .getServiceCodesRunningForDate() .getOrDefault(serviceDate, EMPTY_SERVICE_CODES); } @@ -366,11 +366,40 @@ public List listCanceledTrips() { public List findCanceledTrips(TripOnServiceDateRequest request) { Matcher matcher = TripOnServiceDateMatcherFactory.of( request, - this::findPattern + this::findPattern, + this::findScheduledRunningTime ); return listCanceledTrips().stream().filter(matcher::match).toList(); } + /** + * Resolves a trip's runtime on its service date according to its schedule. The period starts at + * the scheduled departure from the first stop and ends at the scheduled arrival at the last + * stop. + * + * @return {@code null} if the schedule of the trip cannot be resolved. + */ + @Nullable + private TimePeriod findScheduledRunningTime(TripOnServiceDate tripOnServiceDate) { + var trip = tripOnServiceDate.getTrip(); + var serviceDate = tripOnServiceDate.getServiceDate(); + var pattern = findPattern(trip, serviceDate); + if (pattern == null) { + return null; + } + var tripTimes = findTimetable(pattern, serviceDate).getTripTimes(trip); + if (tripTimes == null) { + tripTimes = pattern.getScheduledTimetable().getTripTimes(trip); + } + if (tripTimes == null) { + return null; + } + ZoneId timeZone = trip.getRoute().getAgency().getTimezone(); + return tripTimes.scheduledRunningTime( + ServiceDateUtils.asStartOfService(serviceDate, timeZone).toInstant() + ); + } + @Override public Collection listTrips() { OTPRequestTimeoutException.checkForTimeout(); @@ -610,7 +639,8 @@ public TripOnServiceDate getTripOnServiceDate(TripIdAndServiceDate tripIdAndServ public List findTripsOnServiceDate(TripOnServiceDateRequest request) { Matcher matcher = TripOnServiceDateMatcherFactory.of( request, - this::findPattern + this::findPattern, + this::findScheduledRunningTime ); return listTripsOnServiceDate().stream().filter(matcher::match).toList(); } @@ -646,16 +676,6 @@ public List getTrips(TripRequest request) { return listTrips().stream().filter(matcher::match).toList(); } - /** - * TODO OTP2 - This is NOT THREAD-SAFE and is used in the real-time updaters, we need to fix - * this when doing the issue #3030. - */ - @Override - @Nullable - public FeedScopedId getOrCreateServiceIdForDate(LocalDate serviceDate) { - return transitRepository.getOrCreateServiceIdForDate(serviceDate); - } - @Override public RaptorTransitData getRaptorTransitData() { OTPRequestTimeoutException.checkForTimeout(); @@ -670,7 +690,9 @@ public RaptorTransitData getRealtimeRaptorTransitData() { @Override public TripCalendars getTripCalendars() { - return this.transitRepository.getTripCalendar(); + return timetableSnapshot != null + ? timetableSnapshot.getTripCalendars() + : this.transitRepository.getTripCalendar(); } @Override @@ -707,8 +729,9 @@ public Collection findRegularStopsByBoundingBox( .getSiteRepository() .findRegularStops(request.envelope()); - Matcher matcher = RegularStopMatcherFactory.of(request, stop -> - !findPatterns(stop, true).isEmpty() + Matcher matcher = RegularStopMatcherFactory.of( + request, + stop -> !findPatterns(stop, true).isEmpty() ); return stops.stream().filter(matcher::match).toList(); } @@ -738,12 +761,12 @@ public List findTransitModes(StopLocation stop) { @Override public Set listServiceDates() { - return Collections.unmodifiableSet(transitRepository.getServiceCodesRunningForDate().keySet()); + return Collections.unmodifiableSet(getTripCalendars().getServiceCodesRunningForDate().keySet()); } @Override public Map getServiceCodesRunningForDate() { - return Collections.unmodifiableMap(transitRepository.getServiceCodesRunningForDate()); + return Collections.unmodifiableMap(getTripCalendars().getServiceCodesRunningForDate()); } @Override diff --git a/application/src/main/java/org/opentripplanner/transit/service/PatternByServiceDatesFilter.java b/application/src/main/java/org/opentripplanner/transit/service/PatternByServiceDatesFilter.java index 968a6966bea..20b6d79877b 100644 --- a/application/src/main/java/org/opentripplanner/transit/service/PatternByServiceDatesFilter.java +++ b/application/src/main/java/org/opentripplanner/transit/service/PatternByServiceDatesFilter.java @@ -62,12 +62,10 @@ public Collection filterRoutes(Collection routeStream) { } private boolean hasServicesOnDate(TripPattern pattern) { - return pattern - .scheduledTripsAsStream() - .anyMatch(trip -> { - var dates = getServiceDatesForTrip.apply(trip); + return pattern.scheduledTripsAsStream().anyMatch(trip -> { + var dates = getServiceDatesForTrip.apply(trip); - return dates.stream().anyMatch(range::contains); - }); + return dates.stream().anyMatch(range::contains); + }); } } diff --git a/application/src/main/java/org/opentripplanner/transit/service/TransitRepository.java b/application/src/main/java/org/opentripplanner/transit/service/TransitRepository.java index 01c8cc677a8..3891907c828 100644 --- a/application/src/main/java/org/opentripplanner/transit/service/TransitRepository.java +++ b/application/src/main/java/org/opentripplanner/transit/service/TransitRepository.java @@ -12,7 +12,6 @@ import java.time.Instant; import java.time.LocalDate; import java.time.ZoneId; -import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -34,7 +33,6 @@ import org.opentripplanner.transfer.constrained.ConstrainedTransferService; import org.opentripplanner.transfer.constrained.internal.DefaultConstrainedTransferService; import org.opentripplanner.transit.model.basic.Notice; -import org.opentripplanner.transit.model.calendar.DefaultTripCalendars; import org.opentripplanner.transit.model.calendar.TripCalendars; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; import org.opentripplanner.transit.model.network.BikeAccess; @@ -97,7 +95,7 @@ public class TransitRepository implements Serializable { */ private transient RaptorTransitData raptorTransitData; - private final DefaultTripCalendars tripCalendar = new DefaultTripCalendars(); + private TripCalendars tripCalendars = TripCalendars.empty(); private transient TransitRepositoryIndex index; private ZoneId timeZone = null; @@ -141,7 +139,7 @@ public void index() { assertModificationsAllowed(); if (index == null) { LOG.info("Index timetable repository..."); - this.tripCalendar.initializeServiceCodes(); + this.tripCalendars = this.tripCalendars.initializeServiceCodesRunningForDate(); this.index = new TransitRepositoryIndex(this); LOG.info("Index timetable repository complete."); } @@ -176,42 +174,34 @@ public ConstrainedTransferService getConstrainedTransferService() { * Returns true if this repository contains any transit data at the given instant. */ public boolean transitFeedCovers(Instant time) { - return (!time.isBefore(getTransitServiceStarts()) && time.isBefore(getTransitServiceEnds())); + return !time.isBefore(getTransitServiceStarts()) && time.isBefore(getTransitServiceEnds()); } + /** + * The build-time scheduled calendar. Also used to seed the runtime write buffer held by the + * timetable repository at startup; since {@link TripCalendars} is immutable, sharing this same + * instance is safe, and all further calendar mutations (e.g. real-time trip additions) happen on + * that buffer, not on this repository's own {@code tripCalendars}. Prefer reading trip calendars + * through {@link org.opentripplanner.transit.service.TransitService#getTripCalendars()} on the + * request/write path, which resolves a cached, transaction-consistent snapshot instead. + */ public TripCalendars getTripCalendar() { - return tripCalendar; - } - - public DefaultTripCalendars copyTripCalendarForRealTimeUpdates() { - return tripCalendar.copyOf(); + return tripCalendars; } public void updateCalendarServiceData(CalendarServiceData data) { assertModificationsAllowed(); invalidateIndex(); - tripCalendar.merge(data); + tripCalendars = tripCalendars.merge(data); } /** - * Get or create a serviceId for a given date. This method is used when a new trip is added from a - * realtime data update. It makes sure the date is in the existing transit service period. - *

- * - * @param serviceDate service date for the added service id - * @return service-id for date if it exists or is created. If the given service date is outside the - * service period {@code null} is returned. + * Register {@code code} as the service code for {@code serviceId}. Used during graph build only. */ - @Nullable - public FeedScopedId getOrCreateServiceIdForDate(LocalDate serviceDate) { - // Start of day + public void putServiceCode(FeedScopedId serviceId, int code) { assertModificationsAllowed(); - ZonedDateTime time = ServiceDateUtils.asStartOfService(serviceDate, getTimeZone()); - - if (!transitFeedCovers(time.toInstant())) { - return null; - } - return tripCalendar.getOrCreateServiceIdForDate(serviceDate); + invalidateIndex(); + tripCalendars = tripCalendars.withServiceCode(serviceId, code); } public Collection getFeedIds() { @@ -319,7 +309,7 @@ public void addOperators(Collection operators) { * The time when the transit service start. Will return EPOCH if there is no transit. */ public Instant getTransitServiceStarts() { - return tripCalendar + return tripCalendars .startDate() .map(serviceDate -> ServiceDateUtils.asStartOfService(serviceDate, getTimeZone()).toInstant()) .orElse(Instant.EPOCH); @@ -329,7 +319,7 @@ public Instant getTransitServiceStarts() { * The time when the transit service ends. Will return EPOCH if there is no transit. */ public Instant getTransitServiceEnds() { - return tripCalendar + return tripCalendars .endDate() .map(serviceDate -> ServiceDateUtils.asStartOfService(serviceDate.plusDays(1), getTimeZone()).toInstant() @@ -375,7 +365,7 @@ public List getReplacedByTripOnServiceDate(FeedScopedId id) { * from multiple feeds. */ public Map getServiceCodes() { - return tripCalendar.getServiceCodes(); + return tripCalendars.getServiceCodes(); } public SiteRepository getSiteRepository() { @@ -462,7 +452,7 @@ public GraphUpdaterManager getUpdaterManager() { /** True if there are active transit services loaded into this Graph. */ public boolean hasTransit() { - return !tripCalendar.isEmpty(); + return !tripCalendars.isEmpty(); } public Optional findAgencyById(FeedScopedId id) { @@ -525,7 +515,7 @@ TransitRepositoryIndex getTransitRepositoryIndex() { * For all dates in the system get the service codes that run on it. */ public Map getServiceCodesRunningForDate() { - return tripCalendar.getServiceCodesRunningForDate(); + return tripCalendars.getServiceCodesRunningForDate(); } public boolean isIndexed() { diff --git a/application/src/main/java/org/opentripplanner/transit/service/TransitRepositoryIndex.java b/application/src/main/java/org/opentripplanner/transit/service/TransitRepositoryIndex.java index b8208663824..421c6c47816 100644 --- a/application/src/main/java/org/opentripplanner/transit/service/TransitRepositoryIndex.java +++ b/application/src/main/java/org/opentripplanner/transit/service/TransitRepositoryIndex.java @@ -68,12 +68,10 @@ class TransitRepositoryIndex { for (TripPattern pattern : transitRepository.getAllTripPatterns()) { patternsForRoute.put(pattern.getRoute(), pattern); - pattern - .scheduledTripsAsStream() - .forEach(trip -> { - patternForTrip.put(trip, pattern); - tripForId.put(trip.getId(), trip); - }); + pattern.scheduledTripsAsStream().forEach(trip -> { + patternForTrip.put(trip, pattern); + tripForId.put(trip.getId(), trip); + }); for (StopLocation stop : pattern.getStops()) { patternsForStop.put(stop, pattern); } @@ -217,18 +215,16 @@ private void initializeTheEndOfServiceDateForStop( Map endOfServiceDates = new HashMap<>(); for (StopLocation stop : patternsForStop.keySet()) { for (TripPattern pattern : patternsForStop.get(stop)) { - pattern - .scheduledTripsAsStream() - .forEach(trip -> { - LocalDate tripEndDate = endOfServiceDateForService.get(trip.getServiceId()); - LocalDate endOfServiceDate = endOfServiceDates.get(stop); - if ( - tripEndDate != null && - (endOfServiceDate == null || tripEndDate.isAfter(endOfServiceDate)) - ) { - endOfServiceDates.put(stop, tripEndDate); - } - }); + pattern.scheduledTripsAsStream().forEach(trip -> { + LocalDate tripEndDate = endOfServiceDateForService.get(trip.getServiceId()); + LocalDate endOfServiceDate = endOfServiceDates.get(stop); + if ( + tripEndDate != null && + (endOfServiceDate == null || tripEndDate.isAfter(endOfServiceDate)) + ) { + endOfServiceDates.put(stop, tripEndDate); + } + }); } } endOfServiceDateForStop = Map.copyOf(endOfServiceDates); diff --git a/application/src/main/java/org/opentripplanner/transit/service/TransitService.java b/application/src/main/java/org/opentripplanner/transit/service/TransitService.java index 57993cfd743..57ce10560ee 100644 --- a/application/src/main/java/org/opentripplanner/transit/service/TransitService.java +++ b/application/src/main/java/org/opentripplanner/transit/service/TransitService.java @@ -196,17 +196,6 @@ default List findStopOrChildIds(FeedScopedId id) { @Nullable Trip getScheduledTrip(FeedScopedId id); - /** - * Get or create a serviceId for a given date. This method is used when a new trip is added from - * a real-time data update. It makes sure the date is in the existing transit service period. - * - * @param serviceDate service date for the added service id - * @return service-id for date if it exists or is created. If the given service date is outside - * the service period {@code null} is returned. - */ - @Nullable - FeedScopedId getOrCreateServiceIdForDate(LocalDate serviceDate); - /** * Return all trips, including those created by real-time updates. */ diff --git a/application/src/main/java/org/opentripplanner/updater/DefaultStreetRealTimeUpdateContext.java b/application/src/main/java/org/opentripplanner/updater/DefaultStreetRealTimeUpdateContext.java index 86b58d257f3..bc4bb1642e4 100644 --- a/application/src/main/java/org/opentripplanner/updater/DefaultStreetRealTimeUpdateContext.java +++ b/application/src/main/java/org/opentripplanner/updater/DefaultStreetRealTimeUpdateContext.java @@ -5,5 +5,6 @@ /** * Default implementation of {@link StreetRealTimeUpdateContext}. */ -public record DefaultStreetRealTimeUpdateContext(Graph graph) implements - StreetRealTimeUpdateContext {} +public record DefaultStreetRealTimeUpdateContext( + Graph graph +) implements StreetRealTimeUpdateContext {} diff --git a/application/src/main/java/org/opentripplanner/updater/alert/gtfs/GtfsRealtimeAlertsUpdater.java b/application/src/main/java/org/opentripplanner/updater/alert/gtfs/GtfsRealtimeAlertsUpdater.java index 9642198a1ed..4d36bf661ce 100644 --- a/application/src/main/java/org/opentripplanner/updater/alert/gtfs/GtfsRealtimeAlertsUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/alert/gtfs/GtfsRealtimeAlertsUpdater.java @@ -22,7 +22,8 @@ */ public class GtfsRealtimeAlertsUpdater extends PollingGraphUpdater - implements TransitAlertProvider { + implements TransitAlertProvider +{ private static final Logger LOG = LoggerFactory.getLogger(GtfsRealtimeAlertsUpdater.class); diff --git a/application/src/main/java/org/opentripplanner/updater/alert/siri/SiriAlertsUpdateHandler.java b/application/src/main/java/org/opentripplanner/updater/alert/siri/SiriAlertsUpdateHandler.java index c1f9b7a89eb..9fa7da07d6a 100644 --- a/application/src/main/java/org/opentripplanner/updater/alert/siri/SiriAlertsUpdateHandler.java +++ b/application/src/main/java/org/opentripplanner/updater/alert/siri/SiriAlertsUpdateHandler.java @@ -84,8 +84,9 @@ public void update(ServiceDelivery delivery, TransitRealTimeUpdateContext contex int addedCounter = 0; int expiredCounter = 0; for (PtSituationElement sxElement : situations.getPtSituationElements()) { - boolean expireSituation = (sxElement.getProgress() != null && - sxElement.getProgress().equals(WorkflowStatusEnumeration.CLOSED)); + boolean expireSituation = + sxElement.getProgress() != null && + sxElement.getProgress().equals(WorkflowStatusEnumeration.CLOSED); if (sxElement.getSituationNumber() == null) { continue; @@ -165,12 +166,12 @@ private TransitAlert mapSituationToAlert( if (situation.getValidityPeriods().size() > 0) { ArrayList periods = new ArrayList<>(); for (HalfOpenTimestampOutputRangeStructure activePeriod : situation.getValidityPeriods()) { - final Instant start = activePeriod.getStartTime() != null - ? activePeriod.getStartTime().toInstant().minus(earlyStart) - : null; - final Instant end = activePeriod.getEndTime() != null - ? activePeriod.getEndTime().toInstant() - : null; + final Instant start = + activePeriod.getStartTime() != null + ? activePeriod.getStartTime().toInstant().minus(earlyStart) + : null; + final Instant end = + activePeriod.getEndTime() != null ? activePeriod.getEndTime().toInstant() : null; periods.add(TimePeriod.of(start, end)); } @@ -184,9 +185,10 @@ private TransitAlert mapSituationToAlert( alert.withPriority(situation.getPriority().intValue()); } - var fuzzyTripMatcher = siriFuzzyTripMatcherCache != null - ? new SiriFuzzyTripMatcher(siriFuzzyTripMatcherCache, context.transitService()) - : null; + var fuzzyTripMatcher = + siriFuzzyTripMatcherCache != null + ? new SiriFuzzyTripMatcher(siriFuzzyTripMatcherCache, context.transitService()) + : null; alert.addEntites( new AffectsMapper(feedId, fuzzyTripMatcher, context.transitService()).mapAffects( situation.getAffects() diff --git a/application/src/main/java/org/opentripplanner/updater/alert/siri/SiriSXUpdater.java b/application/src/main/java/org/opentripplanner/updater/alert/siri/SiriSXUpdater.java index 8c73175cab1..423fe61caf5 100644 --- a/application/src/main/java/org/opentripplanner/updater/alert/siri/SiriSXUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/alert/siri/SiriSXUpdater.java @@ -26,7 +26,8 @@ public class SiriSXUpdater extends PollingGraphUpdater - implements TransitAlertProvider { + implements TransitAlertProvider +{ private static final Logger LOG = LoggerFactory.getLogger(SiriSXUpdater.class); private static final int RETRY_MAX_ATTEMPTS = 3; @@ -190,14 +191,14 @@ private Optional getUpdates() { LOG.info( "Retryable exception while reading SIRI feed from {} after {} ms", url, - (System.currentTimeMillis() - t1) + System.currentTimeMillis() - t1 ); throw e; } catch (Exception e) { LOG.error( "Non-retryable exception while reading SIRI feed from {} after {} ms", url, - (System.currentTimeMillis() - t1) + System.currentTimeMillis() - t1 ); } return Optional.empty(); diff --git a/application/src/main/java/org/opentripplanner/updater/spi/ResultLogger.java b/application/src/main/java/org/opentripplanner/updater/spi/ResultLogger.java index e68aaf25113..6a8ec77feb4 100644 --- a/application/src/main/java/org/opentripplanner/updater/spi/ResultLogger.java +++ b/application/src/main/java/org/opentripplanner/updater/spi/ResultLogger.java @@ -38,19 +38,17 @@ public static void logUpdateResultErrors(String feedId, String type, UpdateResul return; } var errorIndex = updateResult.failures(); - errorIndex - .keySet() - .forEach(key -> { - var value = errorIndex.get(key); - var tripIds = value.stream().map(UpdateError::debugId).collect(Collectors.toSet()); - LOG.warn( - "[{} {}] {} failures of {}: {}", - keyValue("feedId", feedId), - keyValue("type", type), - value.size(), - keyValue("errorType", key), - tripIds - ); - }); + errorIndex.keySet().forEach(key -> { + var value = errorIndex.get(key); + var tripIds = value.stream().map(UpdateError::debugId).collect(Collectors.toSet()); + LOG.warn( + "[{} {}] {} failures of {}: {}", + keyValue("feedId", feedId), + keyValue("type", type), + value.size(), + keyValue("errorType", key), + tripIds + ); + }); } } diff --git a/application/src/main/java/org/opentripplanner/updater/trip/gtfs/DuplicatedTripHandler.java b/application/src/main/java/org/opentripplanner/updater/trip/gtfs/DuplicatedTripHandler.java index 09491b8f876..e57f2d4ed8d 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/gtfs/DuplicatedTripHandler.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/gtfs/DuplicatedTripHandler.java @@ -52,7 +52,7 @@ UpdateSuccess handleDuplicated(TripUpdate tripUpdate, UpdateIncrementality updat throw UpdateException.of(tripUpdate.tripId(), TRIP_NOT_FOUND); } - var serviceId = transitService.getOrCreateServiceIdForDate(tripUpdate.startDate()); + var serviceId = buffer.getOrCreateServiceIdForDate(tripUpdate.startDate()); if (serviceId == null) { throw UpdateException.of(tripUpdate.tripId(), OUTSIDE_SERVICE_PERIOD); } diff --git a/application/src/main/java/org/opentripplanner/updater/trip/gtfs/NewTripHandler.java b/application/src/main/java/org/opentripplanner/updater/trip/gtfs/NewTripHandler.java index 6117933d24b..7c6f1787c9c 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/gtfs/NewTripHandler.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/gtfs/NewTripHandler.java @@ -59,7 +59,7 @@ UpdateSuccess handleNew(final TripUpdate tripUpdate) throws UpdateException { if (transitService.getScheduledTrip(tripUpdate.tripId()) != null) { throw UpdateException.of(tripUpdate.tripId(), TRIP_ALREADY_EXISTS); } - var serviceId = transitService.getOrCreateServiceIdForDate(tripUpdate.startDate()); + var serviceId = buffer.getOrCreateServiceIdForDate(tripUpdate.startDate()); if (serviceId == null) { throw UpdateException.of(tripUpdate.tripId(), OUTSIDE_SERVICE_PERIOD); } diff --git a/application/src/main/java/org/opentripplanner/updater/trip/gtfs/interpolation/BackwardsDelayRequiredInterpolator.java b/application/src/main/java/org/opentripplanner/updater/trip/gtfs/interpolation/BackwardsDelayRequiredInterpolator.java index 9f8391db698..5135afbd851 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/gtfs/interpolation/BackwardsDelayRequiredInterpolator.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/gtfs/interpolation/BackwardsDelayRequiredInterpolator.java @@ -31,18 +31,18 @@ protected void fillInMissingTimes(RealTimeTripTimesBuilder builder, int firstUpd if (time == null) { builder.withArrivalTime( firstUpdatedIndex, - time = Math.min( + (time = Math.min( Objects.requireNonNull(builder.getDepartureTime(firstUpdatedIndex)), builder.getScheduledArrivalTime(firstUpdatedIndex) - ) + )) ); } for (int i = firstUpdatedIndex - 1; i >= 0; i--) { if (setNoData && builder.stopRealTimeStates()[i] != StopRealTimeState.CANCELLED) { builder.withNoData(i); } - builder.withDepartureTime(i, time = Math.min(time, builder.getScheduledDepartureTime(i))); - builder.withArrivalTime(i, time = Math.min(time, builder.getScheduledArrivalTime(i))); + builder.withDepartureTime(i, (time = Math.min(time, builder.getScheduledDepartureTime(i)))); + builder.withArrivalTime(i, (time = Math.min(time, builder.getScheduledArrivalTime(i)))); } } } diff --git a/application/src/main/java/org/opentripplanner/updater/trip/gtfs/model/StopTimeUpdate.java b/application/src/main/java/org/opentripplanner/updater/trip/gtfs/model/StopTimeUpdate.java index b97c88524e6..26848bf8a46 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/gtfs/model/StopTimeUpdate.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/gtfs/model/StopTimeUpdate.java @@ -161,10 +161,8 @@ public Optional stopId() { } public Optional stopHeadsign() { - return ( - stopTimeUpdate.hasStopTimeProperties() && - stopTimeUpdate.getStopTimeProperties().hasStopHeadsign() - ) + return stopTimeUpdate.hasStopTimeProperties() && + stopTimeUpdate.getStopTimeProperties().hasStopHeadsign() ? Optional.of(I18NString.of(stopTimeUpdate.getStopTimeProperties().getStopHeadsign())) : Optional.empty(); } @@ -200,9 +198,7 @@ private Optional stop : Optional.empty(); } - private Optional< - MfdzRealtimeExtensions.StopTimePropertiesExtension - > stopTimePropertiesExtension() { + private Optional stopTimePropertiesExtension() { return stopTimeProperties().map(stopTimeProperties -> stopTimeProperties.hasExtension(MfdzRealtimeExtensions.stopTimeProperties) ? stopTimeProperties.getExtension(MfdzRealtimeExtensions.stopTimeProperties) diff --git a/application/src/main/java/org/opentripplanner/updater/trip/gtfs/model/TripUpdate.java b/application/src/main/java/org/opentripplanner/updater/trip/gtfs/model/TripUpdate.java index 023ea1fd2c3..b7f828a6f8a 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/gtfs/model/TripUpdate.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/gtfs/model/TripUpdate.java @@ -90,16 +90,18 @@ public ScheduleRelationship scheduleRelationship() { } public FeedScopedId tripId() { - return tripDescriptor - .tripId() - .map(id -> new FeedScopedId(feedId, id)) - // this should never happen because an empty trip id will lead to an exception in the - // constructor. - .orElseThrow(() -> - new IllegalStateException( - "Trip ID is missing from trip update. This indicates a programming error." + return ( + tripDescriptor + .tripId() + .map(id -> new FeedScopedId(feedId, id)) + // this should never happen because an empty trip id will lead to an exception in the + // constructor. + .orElseThrow(() -> + new IllegalStateException( + "Trip ID is missing from trip update. This indicates a programming error." + ) ) - ); + ); } public void validate() throws DataValidationException, UpdateException { diff --git a/application/src/main/java/org/opentripplanner/updater/trip/gtfs/updater/TripUpdateGraphWriterRunnable.java b/application/src/main/java/org/opentripplanner/updater/trip/gtfs/updater/TripUpdateGraphWriterRunnable.java index b00c26b14a1..2b5a4d9fad6 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/gtfs/updater/TripUpdateGraphWriterRunnable.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/gtfs/updater/TripUpdateGraphWriterRunnable.java @@ -13,7 +13,8 @@ import org.opentripplanner.updater.trip.gtfs.interpolation.ForwardsDelayPropagationType; public class TripUpdateGraphWriterRunnable - implements GraphWriterRunnable { + implements GraphWriterRunnable +{ private final UpdateIncrementality updateIncrementality; diff --git a/application/src/main/java/org/opentripplanner/updater/trip/siri/AddedTripBuilder.java b/application/src/main/java/org/opentripplanner/updater/trip/siri/AddedTripBuilder.java index bd3691b99db..92615a1cbdd 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/siri/AddedTripBuilder.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/siri/AddedTripBuilder.java @@ -29,6 +29,7 @@ import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.model.timetable.TripTimesFactory; +import org.opentripplanner.transit.repository.TimetableRepository; import org.opentripplanner.transit.service.TransitService; import org.opentripplanner.updater.spi.DataValidationExceptionMapper; import org.opentripplanner.updater.spi.UpdateException; @@ -42,6 +43,7 @@ class AddedTripBuilder { private static final Logger LOG = LoggerFactory.getLogger(AddedTripBuilder.class); private final TransitService transitService; + private final TimetableRepository buffer; private final EntityResolver entityResolver; private final ZoneId timeZone; private final Function getTripPatternId; @@ -70,10 +72,12 @@ class AddedTripBuilder { AddedTripBuilder( EstimatedVehicleJourneyWrapper journey, TransitService transitService, + TimetableRepository buffer, DeduplicatorService deduplicator, EntityResolver entityResolver, Function getTripPatternId ) { + this.buffer = buffer; this.deduplicator = deduplicator; // Verifying values required in SIRI Profile // Added ServiceJourneyId @@ -124,6 +128,7 @@ class AddedTripBuilder { AddedTripBuilder( TransitService transitService, + TimetableRepository buffer, DeduplicatorService deduplicator, EntityResolver entityResolver, Function getTripPatternId, @@ -146,6 +151,7 @@ class AddedTripBuilder { @Nullable String vehicleRef ) { this.transitService = transitService; + this.buffer = buffer; this.deduplicator = deduplicator; this.entityResolver = entityResolver; this.timeZone = transitService.getTimeZone(); @@ -179,7 +185,7 @@ TripUpdate build() throws UpdateException { throw UpdateException.of(tripId, NO_START_DATE); } - FeedScopedId calServiceId = transitService.getOrCreateServiceIdForDate(serviceDate); + FeedScopedId calServiceId = buffer.getOrCreateServiceIdForDate(serviceDate); if (calServiceId == null) { throw UpdateException.of(tripId, NO_START_DATE); } @@ -209,7 +215,7 @@ TripUpdate build() throws UpdateException { stopSequence, calls.get(stopSequence), stopSequence == 0, - stopSequence == (calls.size() - 1) + stopSequence == calls.size() - 1 ); // Drop this update if the call refers to an unknown stop (not present in the site repository). @@ -249,7 +255,7 @@ TripUpdate build() throws UpdateException { startOfService, builder, stopSequence, - stopSequence == (calls.size() - 1), + stopSequence == calls.size() - 1, isJourneyPredictionInaccurate, calls.get(stopSequence), occupancy diff --git a/application/src/main/java/org/opentripplanner/updater/trip/siri/EstimatedVehicleJourneyWrapper.java b/application/src/main/java/org/opentripplanner/updater/trip/siri/EstimatedVehicleJourneyWrapper.java index ef3b0af0757..2c253db1f74 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/siri/EstimatedVehicleJourneyWrapper.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/siri/EstimatedVehicleJourneyWrapper.java @@ -37,9 +37,10 @@ final class EstimatedVehicleJourneyWrapper { private EstimatedVehicleJourneyWrapper(EstimatedVehicleJourney journey, List calls) { this.journey = journey; this.calls = calls; - this.code = journey.getEstimatedVehicleJourneyCode() != null - ? new EstimatedVehicleJourneyCode(journey.getEstimatedVehicleJourneyCode()) - : null; + this.code = + journey.getEstimatedVehicleJourneyCode() != null + ? new EstimatedVehicleJourneyCode(journey.getEstimatedVehicleJourneyCode()) + : null; } /* Construction and validation */ diff --git a/application/src/main/java/org/opentripplanner/updater/trip/siri/ExtraCallTripBuilder.java b/application/src/main/java/org/opentripplanner/updater/trip/siri/ExtraCallTripBuilder.java index c22c0afdcec..9b7efb5b232 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/siri/ExtraCallTripBuilder.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/siri/ExtraCallTripBuilder.java @@ -24,6 +24,7 @@ import org.opentripplanner.transit.model.timetable.RealTimeTripTimesBuilder; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimesFactory; +import org.opentripplanner.transit.repository.TimetableRepository; import org.opentripplanner.transit.service.TransitService; import org.opentripplanner.updater.spi.DataValidationExceptionMapper; import org.opentripplanner.updater.spi.UpdateException; @@ -32,6 +33,7 @@ class ExtraCallTripBuilder { private final TransitService transitService; + private final TimetableRepository buffer; private final ZoneId timeZone; private final Function generateTripPatternId; private final Trip trip; @@ -51,11 +53,13 @@ class ExtraCallTripBuilder { ExtraCallTripBuilder( EstimatedVehicleJourneyWrapper journey, TransitService transitService, + TimetableRepository buffer, DeduplicatorService deduplicator, EntityResolver entityResolver, Function generateTripPatternId, Trip trip ) { + this.buffer = buffer; this.trip = Objects.requireNonNull(trip); this.deduplicator = deduplicator; @@ -92,7 +96,7 @@ TripUpdate build() throws UpdateException { throw UpdateException.of(trip.getId(), NO_START_DATE); } - FeedScopedId calServiceId = transitService.getOrCreateServiceIdForDate(serviceDate); + FeedScopedId calServiceId = buffer.getOrCreateServiceIdForDate(serviceDate); if (calServiceId == null) { throw UpdateException.of(trip.getId(), NO_START_DATE); } @@ -112,7 +116,7 @@ TripUpdate build() throws UpdateException { stopSequence, call, stopSequence == 0, - stopSequence == (calls.size() - 1) + stopSequence == calls.size() - 1 ); // Drop this update if the call refers to an unknown stop (not present in the site repository). @@ -168,7 +172,7 @@ TripUpdate build() throws UpdateException { startOfService, builder, stopSequence, - stopSequence == (calls.size() - 1), + stopSequence == calls.size() - 1, isJourneyPredictionInaccurate, calls.get(stopSequence), occupancy diff --git a/application/src/main/java/org/opentripplanner/updater/trip/siri/ModifiedTripBuilder.java b/application/src/main/java/org/opentripplanner/updater/trip/siri/ModifiedTripBuilder.java index 3075d89047c..b8b70a0e9a7 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/siri/ModifiedTripBuilder.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/siri/ModifiedTripBuilder.java @@ -243,7 +243,7 @@ private void applyUpdates(RealTimeTripTimesBuilder builder) { startOfService, builder, stopIndex, - stopIndex == (stopsInPattern.size() - 1), + stopIndex == stopsInPattern.size() - 1, predictionInaccurate, matchingCall, occupancy @@ -312,7 +312,7 @@ static StopPattern createStopPattern( } } var newStopPattern = builder.build(); - return (pattern.isModified() && pattern.getStopPattern().equals(newStopPattern)) + return pattern.isModified() && pattern.getStopPattern().equals(newStopPattern) ? pattern.getStopPattern() : newStopPattern; } diff --git a/application/src/main/java/org/opentripplanner/updater/trip/siri/SiriFuzzyTripMatcher.java b/application/src/main/java/org/opentripplanner/updater/trip/siri/SiriFuzzyTripMatcher.java index b1b446c1a3b..87c8d48ca17 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/siri/SiriFuzzyTripMatcher.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/siri/SiriFuzzyTripMatcher.java @@ -84,9 +84,10 @@ public TripAndPattern match( if (stop == null) { throw UpdateException.of(UNKNOWN_STOP); } - ZonedDateTime arrivalTime = lastCall.getAimedArrivalTime() != null - ? lastCall.getAimedArrivalTime() - : lastCall.getAimedDepartureTime(); + ZonedDateTime arrivalTime = + lastCall.getAimedArrivalTime() != null + ? lastCall.getAimedArrivalTime() + : lastCall.getAimedDepartureTime(); if (arrivalTime != null) { trips = getMatchingTripsOnStopOrSiblings(stop, arrivalTime); @@ -209,9 +210,10 @@ private TripAndPattern getTripAndPatternForJourney( trip.getId(), serviceDate ); - TripPattern tripPattern = newTripPatternForModifiedTrip != null - ? newTripPatternForModifiedTrip - : transitService.findPattern(trip); + TripPattern tripPattern = + newTripPatternForModifiedTrip != null + ? newTripPatternForModifiedTrip + : transitService.findPattern(trip); var firstStop = tripPattern.firstStop(); var lastStop = tripPattern.lastStop(); diff --git a/application/src/main/java/org/opentripplanner/updater/trip/siri/SiriRealTimeTripUpdateAdapter.java b/application/src/main/java/org/opentripplanner/updater/trip/siri/SiriRealTimeTripUpdateAdapter.java index ab6738dc8ad..acaa356412d 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/siri/SiriRealTimeTripUpdateAdapter.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/siri/SiriRealTimeTripUpdateAdapter.java @@ -50,9 +50,10 @@ public SiriRealTimeTripUpdateAdapter( */ public SiriRealTimeUpdateHandler forUpdate(TimetableRepository buffer) { var transitService = new DefaultTransitService(transitRepository, buffer); - var fuzzyTripMatcher = siriFuzzyTripMatcherCache != null - ? new SiriFuzzyTripMatcher(siriFuzzyTripMatcherCache, transitService) - : null; + var fuzzyTripMatcher = + siriFuzzyTripMatcherCache != null + ? new SiriFuzzyTripMatcher(siriFuzzyTripMatcherCache, transitService) + : null; return new SiriRealTimeUpdateHandler( transitService, buffer, diff --git a/application/src/main/java/org/opentripplanner/updater/trip/siri/SiriRealTimeUpdateHandler.java b/application/src/main/java/org/opentripplanner/updater/trip/siri/SiriRealTimeUpdateHandler.java index 47f7626a6f5..a29fde66d7c 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/siri/SiriRealTimeUpdateHandler.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/siri/SiriRealTimeUpdateHandler.java @@ -130,6 +130,7 @@ private UpdateSuccess apply(EstimatedVehicleJourney journey, EntityResolver enti case REPLACEMENT_DEPARTURE -> new AddedTripBuilder( journeyWrapper, transitService, + buffer, deduplicator, entityResolver, tripPatternIdGenerator::generateUniqueTripPatternId @@ -299,6 +300,7 @@ private TripUpdate handleExtraCall( var tripUpdate = new ExtraCallTripBuilder( journey, transitService, + buffer, deduplicator, entityResolver, tripPatternIdGenerator::generateUniqueTripPatternId, diff --git a/application/src/main/java/org/opentripplanner/updater/trip/siri/StopTimesMapper.java b/application/src/main/java/org/opentripplanner/updater/trip/siri/StopTimesMapper.java index bc1a494c18c..84a4c63da4a 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/siri/StopTimesMapper.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/siri/StopTimesMapper.java @@ -49,18 +49,20 @@ StopTime createAimedStopTime( } // Fallback to other time, if one doesn't exist - var aimedArrivalTime = call.getAimedArrivalTime() != null - ? call.getAimedArrivalTime() - : call.getAimedDepartureTime(); + var aimedArrivalTime = + call.getAimedArrivalTime() != null + ? call.getAimedArrivalTime() + : call.getAimedDepartureTime(); var aimedArrivalTimeSeconds = ServiceDateUtils.secondsSinceStartOfService( startOfService, aimedArrivalTime ); - var aimedDepartureTime = call.getAimedDepartureTime() != null - ? call.getAimedDepartureTime() - : call.getAimedArrivalTime(); + var aimedDepartureTime = + call.getAimedDepartureTime() != null + ? call.getAimedDepartureTime() + : call.getAimedArrivalTime(); var aimedDepartureTimeSeconds = ServiceDateUtils.secondsSinceStartOfService( startOfService, diff --git a/application/src/main/java/org/opentripplanner/updater/trip/siri/TimetableHelper.java b/application/src/main/java/org/opentripplanner/updater/trip/siri/TimetableHelper.java index 7ce611809d2..87ae515610f 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/siri/TimetableHelper.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/siri/TimetableHelper.java @@ -86,9 +86,8 @@ public static void applyUpdates( tripTimesBuilder.withExtraCall(index, true); } - OccupancyStatus callOccupancy = call.getOccupancy() != null - ? call.getOccupancy() - : journeyOccupancy; + OccupancyStatus callOccupancy = + call.getOccupancy() != null ? call.getOccupancy() : journeyOccupancy; if (callOccupancy != null) { tripTimesBuilder.withOccupancyStatus(index, callOccupancy); diff --git a/application/src/main/java/org/opentripplanner/updater/trip/siri/updater/SiriETHttpTripUpdateSource.java b/application/src/main/java/org/opentripplanner/updater/trip/siri/updater/SiriETHttpTripUpdateSource.java index 8078474d7a0..9e4675a9df4 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/siri/updater/SiriETHttpTripUpdateSource.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/siri/updater/SiriETHttpTripUpdateSource.java @@ -35,9 +35,10 @@ public class SiriETHttpTripUpdateSource implements EstimatedTimetableSource { public SiriETHttpTripUpdateSource(Parameters parameters, SiriLoader siriLoader) { this.url = parameters.url(); - this.requestorRef = parameters.requestorRef() == null || parameters.requestorRef().isEmpty() - ? "otp-" + UUID.randomUUID() - : parameters.requestorRef(); + this.requestorRef = + parameters.requestorRef() == null || parameters.requestorRef().isEmpty() + ? "otp-" + UUID.randomUUID() + : parameters.requestorRef(); this.siriLoader = siriLoader; } @@ -62,10 +63,10 @@ public Optional getUpdates() { updateIncrementality = DIFFERENTIAL; return siri; } catch (OtpHttpClientException e) { - LOG.info("Failed after {} ms", (System.currentTimeMillis() - t1)); + LOG.info("Failed after {} ms", System.currentTimeMillis() - t1); LOG.warn("Could not get SIRI-ET data from {}", url, e); } catch (Exception e) { - LOG.info("Failed after {} ms", (System.currentTimeMillis() - t1)); + LOG.info("Failed after {} ms", System.currentTimeMillis() - t1); LOG.warn("Failed to parse SIRI-ET feed from {}", url, e); } return Optional.empty(); diff --git a/application/src/main/java/org/opentripplanner/updater/trip/siri/updater/SiriETUpdaterParameters.java b/application/src/main/java/org/opentripplanner/updater/trip/siri/updater/SiriETUpdaterParameters.java index b7701449007..e03e7e227b7 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/siri/updater/SiriETUpdaterParameters.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/siri/updater/SiriETUpdaterParameters.java @@ -4,7 +4,8 @@ import org.opentripplanner.updater.trip.UrlUpdaterParameters; public interface SiriETUpdaterParameters - extends UrlUpdaterParameters, PollingGraphUpdaterParameters { + extends UrlUpdaterParameters, PollingGraphUpdaterParameters +{ String url(); boolean blockReadinessUntilInitialized(); diff --git a/application/src/main/java/org/opentripplanner/updater/trip/siri/updater/google/GooglePubsubEstimatedTimetableSource.java b/application/src/main/java/org/opentripplanner/updater/trip/siri/updater/google/GooglePubsubEstimatedTimetableSource.java index 2d0e1aca492..adbb4b1781c 100644 --- a/application/src/main/java/org/opentripplanner/updater/trip/siri/updater/google/GooglePubsubEstimatedTimetableSource.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/siri/updater/google/GooglePubsubEstimatedTimetableSource.java @@ -206,7 +206,9 @@ private void createSubscription() { .setPushConfig(pushConfig) .setMessageRetentionDuration( // How long will an unprocessed message be kept - minimum 10 minutes - com.google.protobuf.Duration.newBuilder().setSeconds(600).build() + com.google.protobuf.Duration.newBuilder() + .setSeconds(600) + .build() ) .setExpirationPolicy( ExpirationPolicy.newBuilder() @@ -269,23 +271,21 @@ private void initializeData() { final long t1 = System.currentTimeMillis(); var serviceDelivery = fetchAndParseInitialData(); final long t2 = System.currentTimeMillis(); - LOG.info("Fetching and parsing initial data - finished after {} ms", (t2 - t1)); - serviceDelivery - .map(serviceDeliveryConsumer) - .ifPresent(future -> { - try { - future.get(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException(e); - } catch (ExecutionException e) { - throw new RuntimeException(e); - } - }); + LOG.info("Fetching and parsing initial data - finished after {} ms", t2 - t1); + serviceDelivery.map(serviceDeliveryConsumer).ifPresent(future -> { + try { + future.get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } + }); LOG.info( "Pubsub updater initialized after {} ms: [messages: {}, updates: {}, total size: {}, time since startup: {}]", - (System.currentTimeMillis() - t2), + System.currentTimeMillis() - t2, MESSAGE_COUNTER.get(), UPDATE_COUNTER.get(), FileSizeToTextConverter.fileSizeToString(SIZE_COUNTER.get()), diff --git a/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java index e0c3349ac17..bccdb77a5d1 100644 --- a/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java @@ -23,7 +23,8 @@ * updater fetches data from a single {@link DataSource}. */ public class VehicleParkingAvailabilityUpdater - extends PollingGraphUpdater { + extends PollingGraphUpdater +{ private static final Logger LOG = LoggerFactory.getLogger( VehicleParkingAvailabilityUpdater.class diff --git a/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdater.java b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdater.java index 2374431a387..96137f8b154 100644 --- a/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdater.java @@ -87,7 +87,8 @@ protected void runPolling() throws InterruptedException, ExecutionException { } private class VehicleParkingGraphWriterRunnable - implements GraphWriterRunnable { + implements GraphWriterRunnable + { private final Map oldVehicleParkingsById; private final Set updatedVehicleParkings; diff --git a/application/src/main/java/org/opentripplanner/updater/vehicle_position/PollingVehiclePositionUpdater.java b/application/src/main/java/org/opentripplanner/updater/vehicle_position/PollingVehiclePositionUpdater.java index 5b2ce96a98c..f5701443602 100644 --- a/application/src/main/java/org/opentripplanner/updater/vehicle_position/PollingVehiclePositionUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_position/PollingVehiclePositionUpdater.java @@ -18,7 +18,8 @@ * patterns via a GTFS-RT source. */ public class PollingVehiclePositionUpdater - extends PollingGraphUpdater { + extends PollingGraphUpdater +{ private static final Logger LOG = LoggerFactory.getLogger(PollingVehiclePositionUpdater.class); diff --git a/application/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java b/application/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java index ae04395ec89..6bf8aff9aa8 100644 --- a/application/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java @@ -354,9 +354,8 @@ private PatternAndRealtimeVehicle toRealtimeVehicle( throw UpdateException.noTripId(INVALID_INPUT_STRUCTURE); } - var vehiclePositionWithTripId = fuzzyTripMatcher == null - ? vehiclePosition - : fuzzilySetTrip(vehiclePosition); + var vehiclePositionWithTripId = + fuzzyTripMatcher == null ? vehiclePosition : fuzzilySetTrip(vehiclePosition); var tripId = vehiclePositionWithTripId.getTrip().getTripId(); diff --git a/application/src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdater.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdater.java index 36d2087d983..15e9ae49703 100644 --- a/application/src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdater.java @@ -83,10 +83,10 @@ public VehicleRentalUpdater( parameters.sourceParameters().url() ); this.unlinkedPlaceThrottle = Throttle.ofOneSecond(); - this.requireDropOffInsideBusinessArea = parameters.sourceParameters() instanceof - GbfsVehicleRentalDataSourceParameters gbfs - ? gbfs.requireDropOffInsideBusinessArea() - : true; + this.requireDropOffInsideBusinessArea = + parameters.sourceParameters() instanceof GbfsVehicleRentalDataSourceParameters gbfs + ? gbfs.requireDropOffInsideBusinessArea() + : true; // Creation of network linker library will not modify the graph this.linker = vertexLinker; @@ -160,7 +160,8 @@ protected void runPolling() throws InterruptedException, ExecutionException { } private class VehicleRentalGraphWriterRunnable - implements GraphWriterRunnable { + implements GraphWriterRunnable + { private final List stations; private final Set geofencingZones; @@ -197,13 +198,14 @@ public void run(StreetRealTimeUpdateContext context) { // Copy reference to pass into lambda var vrv = vehicleRentalVertex; unlinkedPlaceThrottle.throttle(() -> - // the toString includes the text "Bike rental station" - LOG.warn( - "VehicleRentalPlace is unlinked for {}: {} {}", - nameForLogging, - vrv, - unlinkedPlaceThrottle.setupInfo() - ) + LOG + // the toString includes the text "Bike rental station" + .warn( + "VehicleRentalPlace is unlinked for {}: {} {}", + nameForLogging, + vrv, + unlinkedPlaceThrottle.setupInfo() + ) ); } VehicleRentalEdge.createRentalEdgesForStation(vehicleRentalVertex, station, tempEdges); diff --git a/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/RentalPickupType.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/RentalPickupType.java index 215625a7c52..e2a2e315fe3 100644 --- a/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/RentalPickupType.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/RentalPickupType.java @@ -26,9 +26,7 @@ public enum RentalPickupType implements DocumentedEnum { @Override public String typeDescription() { - return ( - "This is temporary and will be removed in a future version of OTP. Use this to specify the type of rental data that is allowed to be read from the data source." - ); + return "This is temporary and will be removed in a future version of OTP. Use this to specify the type of rental data that is allowed to be read from the data source."; } @Override diff --git a/application/src/main/java/org/opentripplanner/warmup/GtfsWarmupQueryExecutor.java b/application/src/main/java/org/opentripplanner/warmup/GtfsWarmupQueryExecutor.java index bb12f3abda6..32fdb7e124e 100644 --- a/application/src/main/java/org/opentripplanner/warmup/GtfsWarmupQueryExecutor.java +++ b/application/src/main/java/org/opentripplanner/warmup/GtfsWarmupQueryExecutor.java @@ -8,11 +8,10 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.mapping.routerequest.AccessModeMapper; import org.opentripplanner.apis.gtfs.mapping.routerequest.EgressModeMapper; import org.opentripplanner.apis.support.graphql.OtpDataFetcherExceptionHandler; -import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.street.geometry.WgsCoordinate; import org.opentripplanner.street.model.StreetMode; import org.slf4j.Logger; @@ -23,103 +22,103 @@ class GtfsWarmupQueryExecutor implements WarmupQueryStrategy { private static final Logger LOG = LoggerFactory.getLogger(GtfsWarmupQueryExecutor.class); static final String QUERY = """ - query( - $fromLat: CoordinateValue!, $fromLon: CoordinateValue!, - $toLat: CoordinateValue!, $toLon: CoordinateValue!, - $dateTime: PlanDateTimeInput!, - $accessMode: PlanAccessMode!, $egressMode: PlanEgressMode! + query( + $fromLat: CoordinateValue!, $fromLon: CoordinateValue!, + $toLat: CoordinateValue!, $toLon: CoordinateValue!, + $dateTime: PlanDateTimeInput!, + $accessMode: PlanAccessMode!, $egressMode: PlanEgressMode! + ) { + planConnection( + origin: { location: { coordinate: { latitude: $fromLat, longitude: $fromLon } } } + destination: { location: { coordinate: { latitude: $toLat, longitude: $toLon } } } + dateTime: $dateTime + modes: { transit: { access: [$accessMode], egress: [$egressMode] } } ) { - planConnection( - origin: { location: { coordinate: { latitude: $fromLat, longitude: $fromLon } } } - destination: { location: { coordinate: { latitude: $toLat, longitude: $toLon } } } - dateTime: $dateTime - modes: { transit: { access: [$accessMode], egress: [$egressMode] } } - ) { - searchDateTime - pageInfo { startCursor endCursor hasNextPage hasPreviousPage } - routingErrors { code description inputField } - edges { - node { - start - end - duration generalizedCost waitingTime walkDistance - numberOfTransfers - legs { - mode duration distance generalizedCost - start { scheduledTime estimated { time delay } } - end { scheduledTime estimated { time delay } } - realTime realtimeState - transitLeg walkingBike rentedBike - from { - name lat lon - stop { - gtfsId code name platformCode - parentStation { gtfsId name } - } - } - to { - name lat lon - stop { gtfsId code name } - } - intermediatePlaces { - name lat lon - stop { gtfsId name } - arrival { scheduledTime estimated { time delay } } - departure { scheduledTime estimated { time delay } } - } - stopCalls { - stopLocation { ... on Stop { gtfsId name } } - schedule { time { ... on ArrivalDepartureTime { arrival departure } } } - realTime { - arrival { time delay } - departure { time delay } - } - } - route { - gtfsId shortName longName mode - color textColor - agency { gtfsId name } + searchDateTime + pageInfo { startCursor endCursor hasNextPage hasPreviousPage } + routingErrors { code description inputField } + edges { + node { + start + end + duration generalizedCost waitingTime walkDistance + numberOfTransfers + legs { + mode duration distance generalizedCost + start { scheduledTime estimated { time delay } } + end { scheduledTime estimated { time delay } } + realTime realtimeState + transitLeg walkingBike rentedBike + from { + name lat lon + stop { + gtfsId code name platformCode + parentStation { gtfsId name } } - trip { - gtfsId tripHeadsign - route { gtfsId } + } + to { + name lat lon + stop { gtfsId code name } + } + intermediatePlaces { + name lat lon + stop { gtfsId name } + arrival { scheduledTime estimated { time delay } } + departure { scheduledTime estimated { time delay } } + } + stopCalls { + stopLocation { ... on Stop { gtfsId name } } + schedule { time { ... on ArrivalDepartureTime { arrival departure } } } + realTime { + arrival { time delay } + departure { time delay } } + } + route { + gtfsId shortName longName mode + color textColor agency { gtfsId name } - alerts { - alertHeaderText alertDescriptionText - effectiveStartDate effectiveEndDate - alertSeverityLevel - } - pickupBookingInfo { - contactInfo { phoneNumber infoUrl bookingUrl } - message - } - dropOffBookingInfo { - contactInfo { phoneNumber infoUrl bookingUrl } - message - } - fareProducts { - product { name riderCategory { id name } } - } - legGeometry { points length } } + trip { + gtfsId tripHeadsign + route { gtfsId } + } + agency { gtfsId name } + alerts { + alertHeaderText alertDescriptionText + activityPeriods { start end } + alertSeverityLevel + } + pickupBookingInfo { + contactInfo { phoneNumber infoUrl bookingUrl } + message + } + dropOffBookingInfo { + contactInfo { phoneNumber infoUrl bookingUrl } + message + } + fareProducts { + product { name riderCategory { id name } } + } + legGeometry { points length } } } } } - """; + } + """; private final GraphQL graphQL; - private final GraphQLRequestContext requestContext; + private final GtfsGraphQLRequestContext requestContext; private final ModeCombinations modeCombinations; GtfsWarmupQueryExecutor( - OtpServerRequestContext context, + GtfsGraphQLRequestContext requestContext, List accessModes, List egressModes ) { - this.requestContext = GraphQLRequestContext.ofServerContext(context); - this.graphQL = GraphQL.newGraphQL(context.gtfsSchema()) + this.requestContext = requestContext; + this.graphQL = GraphQL.newGraphQL(requestContext.schema()) .defaultDataFetcherExceptionHandler(new OtpDataFetcherExceptionHandler()) .build(); this.modeCombinations = new ModeCombinations(accessModes, egressModes); diff --git a/application/src/main/java/org/opentripplanner/warmup/TransmodelWarmupQueryExecutor.java b/application/src/main/java/org/opentripplanner/warmup/TransmodelWarmupQueryExecutor.java index 439bf67e94f..c1ce0faff06 100644 --- a/application/src/main/java/org/opentripplanner/warmup/TransmodelWarmupQueryExecutor.java +++ b/application/src/main/java/org/opentripplanner/warmup/TransmodelWarmupQueryExecutor.java @@ -8,7 +8,6 @@ import org.opentripplanner.apis.transmodel.TransmodelRequestContext; import org.opentripplanner.apis.transmodel.model.EnumTypes; import org.opentripplanner.apis.transmodel.support.AbortOnUnprocessableRequestExecutionStrategy; -import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.street.geometry.WgsCoordinate; import org.opentripplanner.street.model.StreetMode; import org.slf4j.Logger; @@ -19,110 +18,104 @@ class TransmodelWarmupQueryExecutor implements WarmupQueryStrategy { private static final Logger LOG = LoggerFactory.getLogger(TransmodelWarmupQueryExecutor.class); static final String QUERY = """ - query( - $fromLat: Float!, $fromLon: Float!, - $toLat: Float!, $toLon: Float!, - $arriveBy: Boolean!, - $accessMode: StreetMode!, $egressMode: StreetMode! + query( + $fromLat: Float!, $fromLon: Float!, + $toLat: Float!, $toLon: Float!, + $arriveBy: Boolean!, + $accessMode: StreetMode!, $egressMode: StreetMode! + ) { + trip( + from: { coordinates: { latitude: $fromLat, longitude: $fromLon } } + to: { coordinates: { latitude: $toLat, longitude: $toLon } } + arriveBy: $arriveBy + modes: { accessMode: $accessMode, egressMode: $egressMode } ) { - trip( - from: { coordinates: { latitude: $fromLat, longitude: $fromLon } } - to: { coordinates: { latitude: $toLat, longitude: $toLon } } - arriveBy: $arriveBy - modes: { accessMode: $accessMode, egressMode: $egressMode } - ) { - metadata { searchWindowUsed nextDateTime prevDateTime } - nextPageCursor - previousPageCursor - routingErrors { code description inputField } - tripPatterns { + metadata { searchWindowUsed nextDateTime prevDateTime } + nextPageCursor + previousPageCursor + routingErrors { code description inputField } + tripPatterns { + aimedStartTime expectedStartTime + aimedEndTime expectedEndTime + duration distance streetDistance generalizedCost + systemNotices { tag text } + legs { + mode transportSubmode + duration distance generalizedCost aimedStartTime expectedStartTime aimedEndTime expectedEndTime - duration distance streetDistance generalizedCost - systemNotices { tag text } - legs { - mode transportSubmode - duration distance generalizedCost - aimedStartTime expectedStartTime - aimedEndTime expectedEndTime - realtime ride walkingBike - fromPlace { - name - quay { - id name publicCode - tariffZones { id name } - stopPlace { id name parent { id name } } - } - } - toPlace { - name - quay { id name publicCode } - } - fromEstimatedCall { - aimedDepartureTime expectedDepartureTime realtime cancellation - destinationDisplay { frontText } - notices { id text publicCode } - situations { situationNumber } - } - toEstimatedCall { - aimedArrivalTime expectedArrivalTime - } - intermediateEstimatedCalls { - aimedDepartureTime expectedDepartureTime - quay { id name } + realtime ride walkingBike + fromPlace { + name + quay { + id name publicCode + tariffZones { id name } + stopPlace { id name parent { id name } } } - line { - id publicCode name - presentation { colour textColour } - authority { id name } - operator { id name } - notices { id text publicCode } - } - datedServiceJourney { id operatingDay } - serviceJourney { - id privateCode - journeyPattern { id name notices { id text } } - notices { id text } - } - situations { - situationNumber severity priority - summary { value language } - description { value language } - advice { value language } - validityPeriod { startTime endTime } - infoLinks { uri label } - } - bookingArrangements { - bookingMethods - bookingContact { phone email url } - } - pointsOnLink { points length } - interchangeFrom { staySeated guaranteed maximumWaitTime priority } - interchangeTo { staySeated guaranteed } } + toPlace { + name + quay { id name publicCode } + } + fromEstimatedCall { + aimedDepartureTime expectedDepartureTime realtime cancellation + destinationDisplay { frontText } + notices { id text publicCode } + situations { situationNumber } + } + toEstimatedCall { + aimedArrivalTime expectedArrivalTime + } + intermediateEstimatedCalls { + aimedDepartureTime expectedDepartureTime + quay { id name } + } + line { + id publicCode name + presentation { colour textColour } + authority { id name } + operator { id name } + notices { id text publicCode } + } + datedServiceJourney { id operatingDay } + serviceJourney { + id privateCode + journeyPattern { id name notices { id text } } + notices { id text } + } + situations { + situationNumber severity priority + summary { value language } + description { value language } + advice { value language } + validityPeriod { startTime endTime } + infoLinks { uri label } + } + bookingArrangements { + bookingMethods + bookingContact { phone email url } + } + pointsOnLink { points length } + interchangeFrom { staySeated guaranteed maximumWaitTime priority } + interchangeTo { staySeated guaranteed } } } } - """; + } + """; - private final OtpServerRequestContext serverContext; private final TransmodelRequestContext requestContext; private final GraphQLSchema schema; private final ModeCombinations modeCombinations; TransmodelWarmupQueryExecutor( - OtpServerRequestContext context, + GraphQLSchema schema, + TransmodelRequestContext requestContext, List accessModes, List egressModes ) { - this.serverContext = context; - this.schema = context.transmodelSchema(); - this.requestContext = new TransmodelRequestContext( - context, - context.routingService(), - context.transitService(), - context.empiricalDelayService() - ); + this.schema = schema; + this.requestContext = requestContext; this.modeCombinations = new ModeCombinations(accessModes, egressModes); } @@ -133,7 +126,6 @@ public boolean execute(WgsCoordinate from, WgsCoordinate to, boolean arriveBy, i var input = ExecutionInput.newExecutionInput() .query(QUERY) .context(requestContext) - .root(serverContext) .variables(variables) .build(); diff --git a/application/src/main/java/org/opentripplanner/warmup/WarmupLauncher.java b/application/src/main/java/org/opentripplanner/warmup/WarmupLauncher.java index ceef443c4df..69a46ddcb00 100644 --- a/application/src/main/java/org/opentripplanner/warmup/WarmupLauncher.java +++ b/application/src/main/java/org/opentripplanner/warmup/WarmupLauncher.java @@ -2,7 +2,7 @@ import java.util.function.Supplier; import javax.annotation.Nullable; -import org.opentripplanner.standalone.api.OtpServerRequestContext; +import org.opentripplanner.standalone.configure.RequestScopedFactory; import org.opentripplanner.transit.service.TransitRepository; import org.opentripplanner.updater.GraphUpdaterManager; import org.opentripplanner.warmup.api.WarmupParameters; @@ -24,16 +24,16 @@ public class WarmupLauncher { @Nullable private final WarmupParameters parameters; - private final Supplier serverContextSupplier; + private final Supplier requestScopedFactorySupplier; private final TransitRepository transitRepository; public WarmupLauncher( @Nullable WarmupParameters parameters, - Supplier serverContextSupplier, + Supplier requestScopedFactorySupplier, TransitRepository transitRepository ) { this.parameters = parameters; - this.serverContextSupplier = serverContextSupplier; + this.requestScopedFactorySupplier = requestScopedFactorySupplier; this.transitRepository = transitRepository; } @@ -53,10 +53,10 @@ public void start() { LOG.info("Application warmup configured but no updaters found. Skipping warmup."); return; } - var serverContext = serverContextSupplier.get(); + var requestScopedFactory = requestScopedFactorySupplier.get(); var schema = switch (parameters.api()) { - case TRANSMODEL -> serverContext.transmodelSchema(); - case GTFS -> serverContext.gtfsSchema(); + case TRANSMODEL -> requestScopedFactory.transmodelGraphQLSchema().schema(); + case GTFS -> requestScopedFactory.graphQLRequestContext().schema(); }; if (schema == null) { LOG.warn( @@ -66,7 +66,7 @@ public void start() { ); return; } - var worker = new WarmupWorker(parameters, serverContext, () -> updaterManager); + var worker = new WarmupWorker(parameters, requestScopedFactory, () -> updaterManager); var thread = new Thread(worker, "app-warmup"); thread.setDaemon(true); thread.start(); diff --git a/application/src/main/java/org/opentripplanner/warmup/WarmupWorker.java b/application/src/main/java/org/opentripplanner/warmup/WarmupWorker.java index 6c775384e3b..8f872c1cfae 100644 --- a/application/src/main/java/org/opentripplanner/warmup/WarmupWorker.java +++ b/application/src/main/java/org/opentripplanner/warmup/WarmupWorker.java @@ -3,7 +3,7 @@ import java.time.Duration; import java.time.Instant; import java.util.function.Supplier; -import org.opentripplanner.standalone.api.OtpServerRequestContext; +import org.opentripplanner.standalone.configure.RequestScopedFactory; import org.opentripplanner.updater.GraphUpdaterStatus; import org.opentripplanner.utils.time.DurationUtils; import org.opentripplanner.warmup.api.WarmupParameters; @@ -34,19 +34,20 @@ class WarmupWorker implements Runnable { WarmupWorker( WarmupParameters parameters, - OtpServerRequestContext serverContext, + RequestScopedFactory requestScopedFactory, Supplier updaterStatusProvider ) { this.parameters = parameters; this.updaterStatusProvider = updaterStatusProvider; this.queryStrategy = switch (parameters.api()) { case TRANSMODEL -> new TransmodelWarmupQueryExecutor( - serverContext, + requestScopedFactory.transmodelGraphQLSchema().schema(), + requestScopedFactory.transmodelRequestContext(), parameters.accessModes(), parameters.egressModes() ); case GTFS -> new GtfsWarmupQueryExecutor( - serverContext, + requestScopedFactory.graphQLRequestContext(), parameters.accessModes(), parameters.egressModes() ); diff --git a/application/src/main/java/org/opentripplanner/warmup/configure/WarmupModule.java b/application/src/main/java/org/opentripplanner/warmup/configure/WarmupModule.java index 38152efc9f6..5957cbc76dc 100644 --- a/application/src/main/java/org/opentripplanner/warmup/configure/WarmupModule.java +++ b/application/src/main/java/org/opentripplanner/warmup/configure/WarmupModule.java @@ -34,10 +34,6 @@ static WarmupLauncher provideWarmupLauncher( RequestScopedFactory.Builder requestScopedComponentBuilder, TransitRepository transitRepository ) { - return new WarmupLauncher( - parameters, - () -> requestScopedComponentBuilder.build().createServerContext(), - transitRepository - ); + return new WarmupLauncher(parameters, requestScopedComponentBuilder::build, transitRepository); } } diff --git a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index ae60d7db676..00fe456e7ff 100644 --- a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -135,6 +135,13 @@ type Agency implements Node { "Alert of a current or upcoming disruption in public transportation" type Alert implements Node { + """ + The periods of time when this alert is active, sorted chronologically. There is always at + least one period. Each period has an inclusive start and an exclusive end. A period with an + unbounded start has always been active and a period with an unbounded end is active + indefinitely. + """ + activityPeriods: [OffsetDateTimeRange!]! """ Agency affected by the disruption. Note that this value is present only if the disruption has an effect on all operations of the agency (e.g. in case of a strike). @@ -170,9 +177,9 @@ type Alert implements Node { "Url with more information in all different available languages" alertUrlTranslations: [TranslatedString!]! @deprecated(reason : "Use `alertUrl` instead. `accept-language` header can be used for translations or the `language` parameter on the `alertUrl` field.") "Time when this alert is not in effect anymore. Format: Unix timestamp in seconds" - effectiveEndDate: Long + effectiveEndDate: Long @deprecated(reason : "Use `activityPeriods` instead.") "Time when this alert comes into effect. Format: Unix timestamp in seconds" - effectiveStartDate: Long + effectiveStartDate: Long @deprecated(reason : "Use `activityPeriods` instead.") "Entities affected by the disruption." entities: [AlertEntity] "The feed in which this alert was published" @@ -189,6 +196,47 @@ type Alert implements Node { trip: Trip @deprecated(reason : "Alert can have multiple affected entities now instead of there being duplicate alerts\nfor different entities. This will return only one of the affected trips.\nUse entities instead.") } +""" +A connection to a list of alerts that follows +[GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm). +""" +type AlertConnection { + """ + Edges which contain the alerts. Part of the + [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm). + """ + edges: [AlertEdge] + """ + Contains cursors to fetch more pages of alerts. + Part of the [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm). + """ + pageInfo: PageInfo! + """ + The total number of alerts in this connection at the time of query execution (including the current and previous + pages). + Note, this number might not stay the same throughout the paging as alerts might be added or + removed. + """ + totalCount: Int! +} + +""" +An edge for the alert connection. Part of the +[GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm). +""" +type AlertEdge { + """ + The cursor of the edge. Part of the + [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm). + """ + cursor: String! + """ + Alert as a node. Part of the + [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm). + """ + node: Alert +} + "Arrival and departure time (not relative to midnight)." type ArrivalDepartureTime { "Arrival time as an ISO-8601-formatted datetime." @@ -816,7 +864,23 @@ type Leg { accessibilityScore: Float "For transit legs, the transit agency that operates the service used for this leg. For non-transit legs, `null`." agency: Agency - "Applicable alerts for this leg." + """ + Applicable alerts for this leg. Alerts are added to the leg according to conditions on the following entities: + + - Boarding stop: alerts scoped to that stop, or to that stop combined with the leg's route or trip. + - Alighting stop: same stop/route/trip matching as above. + - Intermediate stops: stops the leg passes through (visits) without boarding or alighting. + Only alerts flagged as relevant to passing through (possible in SIRI, but not GTFS-RT) are + included, and each is checked against that specific stop's scheduled time rather than the leg's + overall time span. + If you wish to include _all_ alerts of the intermediate stops, you can list them, for example in + the `stopCalls` field, and then list their alerts. + - Trip: alerts scoped to the entire trip (optionally limited to a specific service date). + - Route: alerts scoped to the whole route, independent of stop or direction. + - Agency: alerts scoped to the agency, applying across all of its routes and trips. + - Parent stations: for a stop that belongs to a station, alerts on the parent station are included + as well, if it is a boarding or alighting station. + """ alerts: [Alert] """ For transit leg, the offset from the scheduled arrival time of the alighting @@ -1063,6 +1127,20 @@ type Notice { text: String } +""" +A range of time which can be unbounded in either direction. + +The start of the range is inclusive and the end is exclusive. +A `null` start means that the range extends indefinitely into the past and a `null` end means +that it extends indefinitely into the future. +""" +type OffsetDateTimeRange { + "The exclusive end of the range or `null` if the range is unbounded in the future." + end: OffsetDateTime + "The inclusive start of the range or `null` if the range is unbounded in the past." + start: OffsetDateTime +} + type OpeningHours { """ Opening hours for the selected dates using the local time of the parking lot. @@ -1118,6 +1196,18 @@ type Pattern implements Node { Avoid using this when fetching all patterns at once. """ canceledTrips( + """ + Only return canceled trips which are scheduled to be running during one of these time ranges. + A trip is considered to be running from its scheduled departure from the first stop until its + scheduled arrival at the last stop. + + An empty list or a list containing `null` is forbidden. If this argument is not provided or its + value is `null`, no filtering is applied. + + If both `runningTimeRanges` and `serviceDateRanges` are defined, a trip has to match both of + them to be returned. + """ + runningTimeRanges: [OffsetDateTimeRangeInput!], """ Only return canceled trips whose service date falls within one of these ranges. An empty list or a list containing `null` is forbidden. If this argument is not provided or its @@ -1376,7 +1466,33 @@ type QueryType { severityLevel: [AlertSeverityLevelType!], "Only return alerts affecting these stops" stop: [String!] - ): [Alert] @timingData + ): [Alert] @deprecated(reason : "Use alertsConnection or alerts fields within specific types instead.") @timingData + "Get all active alerts" + alertsConnection( + """ + This parameter is part of the [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm) + and should be used together with the `first` parameter. + """ + after: String, + """ + This parameter is part of the [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm) + and should be used together with the `last` parameter. + """ + before: String, + "Can be used to filter the results. When paging, the filter should not be changed between pages." + filters: [AlertsFilterInput!], + """ + Limits how many alerts are returned. This parameter is part of the + [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm) and can be used together with + the `after` parameter. + """ + first: Int, + """ + This parameter is part of the [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm) + and should be used together with the `before` parameter. + """ + last: Int + ): AlertConnection @timingData "Get a single bike park based on its ID, i.e. value of field `bikeParkId`" bikePark(id: String!): BikePark @deprecated(reason : "bikePark is deprecated. Use vehicleParking instead.") @timingData "Get all bike parks" @@ -2435,7 +2551,19 @@ type Stop implements Node & PlaceInterface { If omitted (or `null`), no service date filter is applied and canceled calls across the entire transit service period are returned. Defining a range is recommended. """ - serviceDateRanges: [LocalDateRangeInput!] + serviceDateRanges: [LocalDateRangeInput!], + """ + Only include canceled calls where the vehicle is scheduled to visit this stop during one of + these time ranges. The visit at a stop lasts from the scheduled arrival at the stop until the + scheduled departure from it. + + An empty list or a list containing `null` is forbidden. If this argument is not provided or its + value is `null`, no filtering is applied. + + If both `timeRanges` and `serviceDateRanges` are defined, a call has to match both of + them to be returned. + """ + timeRanges: [OffsetDateTimeRangeInput!] ): [StopCallOnTripOnServiceDate!]! "The cluster which this stop is part of" cluster: Cluster @deprecated(reason : "Not implemented") @@ -3259,7 +3387,7 @@ type step { "The cardinal (compass) direction (e.g. north, northeast) taken when engaging this step." absoluteDirection: AbsoluteDirection "A list of alerts (e.g. construction, detours) applicable to the step." - alerts: [Alert] + alerts: [Alert] @deprecated(reason : "Not implemented") """ This step is on an open area, such as a plaza or train platform, and thus the directions should say something like "cross". @@ -4344,6 +4472,50 @@ input AccessibilityPreferencesInput { wheelchair: WheelchairPreferencesInput } +""" +A collection of selectors for including or excluding alerts from the alerts search. +An alert matches a filter if it matches at least one of the `include` selectors and none of the +`exclude` selectors. When several filters are given, an alert matches if it matches any of them. +""" +input AlertsFilterInput @oneOf { + """ + A list of selectors for excluding alerts. + + An empty list or a list containing `null` is forbidden. + """ + exclude: [AlertsFilterSelectInput!] + """ + A list of selectors for including alerts. + + An empty list or a list containing `null` is forbidden. + """ + include: [AlertsFilterSelectInput!] +} + +""" +A single selector for alerts. The fields of a selector are combined with AND semantics: an alert +must match all of the given fields. Each field is matched if the alert matches any of its values. +Fields that are not set are ignored. An empty list is forbidden. +""" +input AlertsFilterSelectInput { + """ + Matches alerts which are active during any of these time ranges. An alert matches if any of its + active periods overlaps any of the given ranges. + """ + activePeriods: [OffsetDateTimeRangeInput!] + "Matches alerts which have any of these causes." + causes: [AlertCauseType!] + "Matches alerts which have any of these effects." + effects: [AlertEffectType!] + """ + Matches alerts which belong to any of these feeds. The values are feed ids, i.e. the part + before the colon in an id such as `HSL:1234`. + """ + feeds: [String!] + "Matches alerts which have any of these severity levels." + severityLevels: [AlertSeverityLevelType!] +} + "Preferences related to alighting from a transit vehicle." input AlightPreferencesInput { "What is the required minimum time alighting from a vehicle." @@ -4483,6 +4655,15 @@ input CanceledTripsFilterSelectInput { "Canceled trips from these transit modes should be included/excluded." modes: [TransitMode!] """ + Canceled trips are included/excluded based on if they are scheduled to be running during any of + these time ranges. A trip is considered to be running from its scheduled departure from the first + stop until its scheduled arrival at the last stop. + + If both `runningTimeRanges` and `serviceDateRanges` are defined, a trip has to match both of + them to be included/excluded. + """ + runningTimeRanges: [OffsetDateTimeRangeInput!] + """ Canceled trips are included/excluded based on if their service date (but not necessarily their running date) is within any of these time ranges. """ @@ -4510,6 +4691,15 @@ input CanceledTripsSummaryFilterSelectInput { "Canceled trips from these transit modes should be included/excluded." modes: [TransitMode!] """ + Canceled trips are included/excluded based on if they are scheduled to be running during any of + these time ranges. A trip is considered to be running from its scheduled departure from the first + stop until its scheduled arrival at the last stop. + + If both `runningTimeRanges` and `serviceDateRanges` are defined, a trip has to match both of + them to be included/excluded. + """ + runningTimeRanges: [OffsetDateTimeRangeInput!] + """ Canceled trips are included/excluded based on if their service date is within any of these time ranges. """ @@ -4774,6 +4964,29 @@ input LocalDateRangeInput { start: LocalDate } +""" +Filters an entity by a time range. Both ends of the range are optional which makes it possible +to define a range which is open ended in either or both directions. +""" +input OffsetDateTimeRangeInput { + """ + **Exclusive** end time of the filter. This means that an entity which is exactly at `end` is not + selected. + + If `null` this means that no end filter is applied and all entities that are after or at `start` + are selected. + """ + end: OffsetDateTime + """ + **Inclusive** start time of the filter. This means that an entity which is exactly at `start` is + selected. + + If `null` this means that no `start` filter is applied and all entities that are before `end` are + selected. + """ + start: OffsetDateTime +} + """ The filter definition to include or exclude parking facilities used during routing. diff --git a/application/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/application/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index bf43b256ff0..8d817bc5020 100644 --- a/application/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/application/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -611,7 +611,9 @@ type PtSituationElement { "Summary of situation in all different translations available" summary: [MultilingualString!]! "Period this situation is in effect" - validityPeriod: ValidityPeriod + validityPeriod: ValidityPeriod @deprecated(reason : "Use validityPeriods instead") + "The periods in which this situation is valid, sorted in chronological order. There is always at least one period." + validityPeriods: [ValidityPeriod!]! "Operator's version number for the situation element." version: Int "Timestamp when the situation element was updated." @@ -1641,9 +1643,9 @@ type TripSearchData { } type ValidityPeriod { - "End of validity period. Will return 'null' if validity is open-ended." + "The exclusive end of the validity period. Will return 'null' if the validity has an unbounded end." endTime: DateTime - "Start of validity period" + "The inclusive start of the validity period. Will return 'null' if the validity has an unbounded start." startTime: DateTime } @@ -2068,6 +2070,7 @@ enum TransportMode { air bus cableway + carpool coach funicular lift diff --git a/application/src/test-fixtures/java/org/opentripplanner/apis/support/graphql/DataFetchingSupport.java b/application/src/test-fixtures/java/org/opentripplanner/apis/support/graphql/DataFetchingSupport.java index 819138a8c42..42248e82cab 100644 --- a/application/src/test-fixtures/java/org/opentripplanner/apis/support/graphql/DataFetchingSupport.java +++ b/application/src/test-fixtures/java/org/opentripplanner/apis/support/graphql/DataFetchingSupport.java @@ -10,7 +10,7 @@ import graphql.schema.DataFetchingEnvironment; import graphql.schema.DataFetchingEnvironmentImpl; import java.util.Map; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.transit.service.DefaultTransitService; import org.opentripplanner.transit.service.TransitRepository; import org.opentripplanner.transit.service.TransitService; @@ -45,7 +45,7 @@ public static DataFetchingEnvironment dataFetchingEnvironment( .source(source) .arguments(arguments) .context( - new GraphQLRequestContext( + new GtfsGraphQLRequestContext( null, service, null, diff --git a/application/src/test-fixtures/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningUtils.java b/application/src/test-fixtures/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningUtils.java index 72af521f566..dc85cbb786b 100644 --- a/application/src/test-fixtures/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningUtils.java +++ b/application/src/test-fixtures/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningUtils.java @@ -5,12 +5,13 @@ import org.opentripplanner.graph_builder.module.osm.OsmModuleTestFactory; import org.opentripplanner.osm.DefaultOsmProvider; import org.opentripplanner.street.graph.Graph; +import org.opentripplanner.street.graph.summary.GraphSummarizer; import org.opentripplanner.transit.service.SiteRepository; import org.opentripplanner.transit.service.TransitRepository; class IslandPruningUtils { - static Graph buildOsmGraph(File osmFile, IslandPruningParameters parameters) { + static GraphSummarizer buildOsmGraph(File osmFile, IslandPruningParameters parameters) { try { var graph = new Graph(); var osmProvider = new DefaultOsmProvider(osmFile, true); @@ -25,7 +26,7 @@ static Graph buildOsmGraph(File osmFile, IslandPruningParameters parameters) { prune(graph, parameters); - return graph; + return new GraphSummarizer(graph); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/application/src/test-fixtures/java/org/opentripplanner/graph_builder/module/islandpruning/TestNamer.java b/application/src/test-fixtures/java/org/opentripplanner/graph_builder/module/islandpruning/TestNamer.java index 18c331d418f..035da42520c 100644 --- a/application/src/test-fixtures/java/org/opentripplanner/graph_builder/module/islandpruning/TestNamer.java +++ b/application/src/test-fixtures/java/org/opentripplanner/graph_builder/module/islandpruning/TestNamer.java @@ -2,9 +2,9 @@ import org.opentripplanner.core.model.i18n.I18NString; import org.opentripplanner.core.model.i18n.NonLocalizedString; -import org.opentripplanner.graph_builder.module.osm.OsmDatabase; -import org.opentripplanner.graph_builder.module.osm.StreetEdgePair; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.model.StreetEdgePair; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; import org.opentripplanner.osm.model.OsmEntity; import org.opentripplanner.osm.model.OsmWay; diff --git a/application/src/test-fixtures/java/org/opentripplanner/osm/TestOsmProvider.java b/application/src/test-fixtures/java/org/opentripplanner/osm/TestOsmProvider.java index ba1d23afd7d..b6ae885edf3 100644 --- a/application/src/test-fixtures/java/org/opentripplanner/osm/TestOsmProvider.java +++ b/application/src/test-fixtures/java/org/opentripplanner/osm/TestOsmProvider.java @@ -7,7 +7,7 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; import org.opentripplanner._support.time.ZoneIds; -import org.opentripplanner.graph_builder.module.osm.OsmDatabase; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; import org.opentripplanner.osm.model.OsmEntity; import org.opentripplanner.osm.model.OsmNode; import org.opentripplanner.osm.model.OsmRelation; diff --git a/application/src/test-fixtures/java/org/opentripplanner/standalone/api/TestServerContext.java b/application/src/test-fixtures/java/org/opentripplanner/standalone/api/TestServerContext.java index 6ab9ad28b03..dafd482d009 100644 --- a/application/src/test-fixtures/java/org/opentripplanner/standalone/api/TestServerContext.java +++ b/application/src/test-fixtures/java/org/opentripplanner/standalone/api/TestServerContext.java @@ -5,12 +5,9 @@ import java.time.LocalDate; import java.util.List; import java.util.Optional; -import javax.annotation.Nullable; import org.opentripplanner.ext.emission.internal.DefaultEmissionRepository; import org.opentripplanner.ext.emission.internal.DefaultEmissionService; import org.opentripplanner.ext.emission.internal.itinerary.EmissionItineraryDecorator; -import org.opentripplanner.ext.fares.service.gtfs.v1.DefaultFareService; -import org.opentripplanner.ext.flex.FlexParameters; import org.opentripplanner.framework.transaction.api.RepositoryHandle; import org.opentripplanner.framework.transaction.internal.TransactionFactory; import org.opentripplanner.raptor.configure.RaptorConfig; @@ -19,16 +16,14 @@ import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitTuningParameters; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripSchedule; import org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers.RaptorTransitDataMapper; -import org.opentripplanner.routing.api.request.RouteRequest; -import org.opentripplanner.routing.fares.FareService; +import org.opentripplanner.routing.api.RoutingService; import org.opentripplanner.routing.impl.TransitAlertServiceImpl; import org.opentripplanner.routing.linking.LinkingContextFactory; import org.opentripplanner.routing.linking.VertexLinkerTestFactory; import org.opentripplanner.routing.linking.internal.VertexCreationService; +import org.opentripplanner.routing.service.DefaultRoutingService; import org.opentripplanner.routing.via.ViaCoordinateTransferFactory; import org.opentripplanner.routing.via.service.DefaultViaCoordinateTransferFactory; -import org.opentripplanner.service.realtimevehicles.internal.DefaultRealtimeVehicleRepository; -import org.opentripplanner.service.realtimevehicles.internal.RealtimeVehicleRepositoryLifecycle; import org.opentripplanner.service.streetdetails.StreetDetailsService; import org.opentripplanner.service.streetdetails.internal.DefaultStreetDetailsRepository; import org.opentripplanner.service.streetdetails.internal.DefaultStreetDetailsService; @@ -42,10 +37,8 @@ import org.opentripplanner.service.worldenvelope.internal.DefaultWorldEnvelopeRepository; import org.opentripplanner.service.worldenvelope.internal.DefaultWorldEnvelopeService; import org.opentripplanner.service.worldenvelope.model.WorldEnvelope; -import org.opentripplanner.standalone.config.DebugUiConfig; import org.opentripplanner.standalone.config.RouterConfig; import org.opentripplanner.standalone.config.routerconfig.RaptorEnvironmentFactory; -import org.opentripplanner.standalone.server.DefaultServerRequestContext; import org.opentripplanner.street.graph.Graph; import org.opentripplanner.street.internal.DefaultStreetRepository; import org.opentripplanner.street.linking.VertexLinker; @@ -53,8 +46,6 @@ import org.opentripplanner.street.service.StreetLimitationParametersService; import org.opentripplanner.transfer.regular.TransferRepository; import org.opentripplanner.transfer.regular.TransferServiceTestFactory; -import org.opentripplanner.transfer.regular.internal.DefaultTransferRepository; -import org.opentripplanner.transfer.regular.internal.TransferIndex; import org.opentripplanner.transit.repository.DefaultTimetableRepository; import org.opentripplanner.transit.repository.TimetableRepository; import org.opentripplanner.transit.repository.TimetableRepositoryLifecycle; @@ -67,43 +58,37 @@ public class TestServerContext { private TestServerContext() {} - /** Create a context for unit testing using default RoutingRequest. */ - public static OtpServerRequestContext createServerContext( - Graph graph, + /** + * Create a {@link TransitService} for unit testing: indexes the transit repository, builds + * raptor transit data, and wraps a pinned timetable snapshot. + */ + public static TransitService createTransitService( TransitRepository transitRepository, - TransferRepository transferRepository, - FareService fareService + TransferRepository transferRepository ) { - return createServerContext( - graph, + var registry = TransactionFactory.createRepositoryRegistry(); + var timetableHandle = indexAndRegisterTimetableSnapshot( transitRepository, transferRepository, - fareService, - null, - null + registry + ); + return new DefaultTransitService( + transitRepository, + timetableHandle.repositorySnapshot(registry.scope()) ); } - /** Create a context for unit testing */ - public static OtpServerRequestContext createServerContext( - Graph graph, + private static RepositoryHandle< + TimetableRepositorySnapshot, + TimetableRepository + > indexAndRegisterTimetableSnapshot( TransitRepository transitRepository, TransferRepository transferRepository, - FareService fareService, - @Nullable RouteRequest request, - @Nullable FlexParameters flexParameters + org.opentripplanner.framework.transaction.RepositoryRegistry registry ) { - var routerConfig = RouterConfig.DEFAULT; - - if (request == null) { - request = routerConfig.routingRequestDefaults(); - } - if (flexParameters == null) { - flexParameters = routerConfig.flexParameters(); - } transitRepository.index(); - TransitTuningParameters tuningParameters = routerConfig.transitTuningConfig(); + TransitTuningParameters tuningParameters = RouterConfig.DEFAULT.transitTuningConfig(); var scheduledRaptorData = RaptorTransitDataMapper.map( tuningParameters, transitRepository, @@ -111,125 +96,49 @@ public static OtpServerRequestContext createServerContext( ); transitRepository.initRaptorTransitData(scheduledRaptorData); - var registry = TransactionFactory.createRepositoryRegistry(); var timetableSnapshot = new DefaultTimetableRepository( new RaptorTransitData(transitRepository.getRaptorTransitData()), - transitRepository.copyTripCalendarForRealTimeUpdates() + transitRepository.getTripCalendar() ); - RepositoryHandle timetableHandle = - registry.registerRepositorySnapshot( - timetableSnapshot, - new TimetableRepositoryLifecycle(timetableSnapshot, false, LocalDate::now) - ); - - return buildContext( - graph, - transitRepository, - transferRepository, - fareService, - request, - flexParameters, - routerConfig, - registry, - timetableHandle + return registry.registerRepositorySnapshot( + timetableSnapshot, + new TimetableRepositoryLifecycle(timetableSnapshot, false, LocalDate::now) ); } /** - * Create a context for unit testing using an existing repository handle (e.g. when real-time - * updates have already been applied to that handle before context creation). + * Create a {@link RoutingService} for unit testing. */ - public static OtpServerRequestContext createServerContext( + public static RoutingService createRoutingService( Graph graph, - TransitRepository transitRepository, - TransferRepository transferRepository, - FareService fareService, - RepositoryHandle timetableHandle, - org.opentripplanner.framework.transaction.RepositoryRegistry registry, - @Nullable RouteRequest request, - @Nullable FlexParameters flexParameters + TransitService transitService, + TransferRepository transferRepository ) { var routerConfig = RouterConfig.DEFAULT; - if (request == null) { - request = routerConfig.routingRequestDefaults(); - } - if (flexParameters == null) { - flexParameters = routerConfig.flexParameters(); - } - return buildContext( - graph, - transitRepository, - transferRepository, - fareService, - request, - flexParameters, - routerConfig, - registry, - timetableHandle - ); - } - - private static OtpServerRequestContext buildContext( - Graph graph, - TransitRepository transitRepository, - TransferRepository transferRepository, - FareService fareService, - RouteRequest request, - FlexParameters flexParameters, - RouterConfig routerConfig, - org.opentripplanner.framework.transaction.RepositoryRegistry registry, - RepositoryHandle timetableHandle - ) { - var transactionScope = registry.scope(); - var transitService = new DefaultTransitService( - transitRepository, - timetableHandle.repositorySnapshot(transactionScope) - ); - - var raptorConfig = new RaptorConfig( - routerConfig.transitTuningConfig(), - RaptorEnvironmentFactory.create(routerConfig.transitTuningConfig().searchThreadPoolSize()) - ); - + var raptorConfig = createRaptorConfig(); var vertexLinker = createVertexLinker(graph); - return new DefaultServerRequestContext( - DebugUiConfig.DEFAULT, - fareService, - flexParameters, + return new DefaultRoutingService( + transitService, + new TransitAlertServiceImpl(), graph, - createLinkingContextFactory(graph, vertexLinker, transitService), - Metrics.globalRegistry, - routerConfig.ojpApiParameters(), raptorConfig, - new RealtimeVehicleRepositoryLifecycle().freeze(new DefaultRealtimeVehicleRepository()), - List.of(), - request, + Metrics.globalRegistry, createStreetLimitationParametersService(), - TransferServiceTestFactory.transferService(transferRepository), - transactionScope, - routerConfig.transitTuningConfig(), - transitService, - new TransitAlertServiceImpl(), - routerConfig.triasApiParameters(), - routerConfig.gtfsApiParameters(), - routerConfig.vectorTileConfig(), - createVehicleParkingService(), createVehicleRentalService(), - vertexLinker, - createViaTransferResolver(graph, transitService), - createWorldEnvelopeService(), - null, - null, - createEmissionsItineraryDecorator(), createStreetDetailsService(), + TransferServiceTestFactory.transferService(transferRepository), + routerConfig.flexParameters(), + List.of(), null, null, + createViaTransferResolver(graph, transitService), null, + createEmissionsItineraryDecorator(), null, - null, - null, - null + createLinkingContextFactory(graph, vertexLinker, transitService), + routerConfig.transitTuningConfig(), + routerConfig.transitTuningConfig() ); } @@ -237,6 +146,14 @@ private static VertexLinker createVertexLinker(Graph graph) { return VertexLinkerTestFactory.of(graph); } + public static RaptorConfig createRaptorConfig() { + var routerConfig = RouterConfig.DEFAULT; + return new RaptorConfig<>( + routerConfig.transitTuningConfig(), + RaptorEnvironmentFactory.create(routerConfig.transitTuningConfig().searchThreadPoolSize()) + ); + } + /** Static factory method to create a service for test purposes. */ public static WorldEnvelopeService createWorldEnvelopeService() { var repository = new DefaultWorldEnvelopeRepository(); @@ -292,13 +209,4 @@ public static LinkingContextFactory createLinkingContextFactory( } ); } - - public static OtpServerRequestContext ofGraph(Graph graph) { - return createServerContext( - graph, - new TransitRepository(), - new DefaultTransferRepository(new TransferIndex()), - new DefaultFareService() - ); - } } diff --git a/application/src/test-fixtures/java/org/opentripplanner/transit/model/TransitRepositoryTestBuilder.java b/application/src/test-fixtures/java/org/opentripplanner/transit/model/TransitRepositoryTestBuilder.java index da9c068394c..b0df445ca0a 100644 --- a/application/src/test-fixtures/java/org/opentripplanner/transit/model/TransitRepositoryTestBuilder.java +++ b/application/src/test-fixtures/java/org/opentripplanner/transit/model/TransitRepositoryTestBuilder.java @@ -89,22 +89,18 @@ public TransitRepository build(SiteRepository siteRepository) { int serviceCodeCounter = 0; for (var serviceCode : serviceCodes.values()) { calendarServiceData.putServiceDatesForServiceId(serviceCode.id(), serviceCode.serviceDates()); - transitRepository.getServiceCodes().put(serviceCode.id(), serviceCodeCounter); + transitRepository.putServiceCode(serviceCode.id(), serviceCodeCounter); serviceCodeCounter += 1; } transitRepository.updateCalendarServiceData(calendarServiceData); - transitRepository - .getAllTripPatterns() - .forEach(pattern -> { - pattern.getScheduledTimetable().setServiceCodes(transitRepository.getServiceCodes()); - }); + transitRepository.getAllTripPatterns().forEach(pattern -> { + pattern.getScheduledTimetable().setServiceCodes(transitRepository.getServiceCodes()); + }); - transitRepository - .getAllTripPatterns() - .forEach(pattern -> { - pattern.getScheduledTimetable().setServiceCodes(transitRepository.getServiceCodes()); - }); + transitRepository.getAllTripPatterns().forEach(pattern -> { + pattern.getScheduledTimetable().setServiceCodes(transitRepository.getServiceCodes()); + }); transitRepository.addScheduledStopPointMapping(scheduledStopPointMapping); @@ -150,7 +146,9 @@ public Route route(String id, Operator operator) { } public Operator operator(String operatorId) { - var operator = Operator.of(id(operatorId)).withName(operatorId + " name").build(); + var operator = Operator.of(id(operatorId)) + .withName(operatorId + " name") + .build(); operators.add(operator); return operator; } diff --git a/application/src/test-fixtures/java/org/opentripplanner/transit/model/TransitTestEnvironment.java b/application/src/test-fixtures/java/org/opentripplanner/transit/model/TransitTestEnvironment.java index d0e175745c8..03b44607fe8 100644 --- a/application/src/test-fixtures/java/org/opentripplanner/transit/model/TransitTestEnvironment.java +++ b/application/src/test-fixtures/java/org/opentripplanner/transit/model/TransitTestEnvironment.java @@ -4,6 +4,7 @@ import java.time.LocalDate; import java.time.ZoneId; +import java.util.concurrent.ExecutionException; import org.opentripplanner.LocalTimeParser; import org.opentripplanner.core.model.id.FeedScopedIdForTestFactory; import org.opentripplanner.framework.transaction.RepositoryRegistry; @@ -17,6 +18,7 @@ import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.transfer.regular.TransferRepository; import org.opentripplanner.transit.model.network.grouppriority.TransitGroupPriorityService; +import org.opentripplanner.transit.model.timetable.RealTimeTripUpdate; import org.opentripplanner.transit.repository.DefaultTimetableRepository; import org.opentripplanner.transit.repository.TimetableRepository; import org.opentripplanner.transit.repository.TimetableRepositoryLifecycle; @@ -71,7 +73,7 @@ public static TransitTestEnvironmentBuilder of(LocalDate serviceDate, ZoneId tim this.repositoryRegistry = TransactionFactory.createRepositoryRegistry(); var timetableSnapshot = new DefaultTimetableRepository( new RaptorTransitData(transitRepository.getRaptorTransitData()), - transitRepository.copyTripCalendarForRealTimeUpdates() + transitRepository.getTripCalendar() ); this.timetableHandle = repositoryRegistry.registerRepositorySnapshot( timetableSnapshot, @@ -108,6 +110,25 @@ public TransitService transitService() { return new DefaultTransitService(transitRepository, timetableSnapshot()); } + /** + * Applies a real-time update through the transaction framework, committing it to the timetable + * repository backing {@link #transitService()}, so that a subsequent call to that method + * returns a snapshot reflecting the update. The method will wait for the update to be applied + * before returning. + */ + public void applyUpdate(RealTimeTripUpdate update) { + try { + var task = updateManager.submit(ctx -> { + TimetableRepository repository = ctx.repository(timetableHandle); + repository.update(update); + }); + // Wait for task to commit - this allows us to proceed with the test + task.get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + public String feedId() { return FeedScopedIdForTestFactory.FEED_ID; } diff --git a/application/src/test-fixtures/java/org/opentripplanner/transit/model/TripInput.java b/application/src/test-fixtures/java/org/opentripplanner/transit/model/TripInput.java index 9f1b08202d4..09c5b3bcb9a 100644 --- a/application/src/test-fixtures/java/org/opentripplanner/transit/model/TripInput.java +++ b/application/src/test-fixtures/java/org/opentripplanner/transit/model/TripInput.java @@ -259,8 +259,11 @@ public StopLocation stopLocation() { } } - private record FlexStopCallInput(AreaStop stop, int windowStart, int windowEnd) implements - StopCallInput { + private record FlexStopCallInput( + AreaStop stop, + int windowStart, + int windowEnd + ) implements StopCallInput { public StopTime toStopTime(Trip trip, int stopSequence) { var st = new StopTime(); st.setTrip(trip); diff --git a/application/src/test-fixtures/java/org/opentripplanner/transit/model/TripTimesStringBuilder.java b/application/src/test-fixtures/java/org/opentripplanner/transit/model/TripTimesStringBuilder.java index 9504e80a10f..ad2c152b7bb 100644 --- a/application/src/test-fixtures/java/org/opentripplanner/transit/model/TripTimesStringBuilder.java +++ b/application/src/test-fixtures/java/org/opentripplanner/transit/model/TripTimesStringBuilder.java @@ -62,8 +62,7 @@ public static String encodeTripTimes(TripTimes tripTimes, TripPattern pattern) { if (!flags.isEmpty()) { s.append(" [").append(String.join(",", flags)).append("]"); } - s - .append(" ") + s.append(" ") .append(TimeUtils.timeToStrCompact(arrive)) .append(" ") .append(TimeUtils.timeToStrCompact(depart)); diff --git a/application/src/test/java/org/opentripplanner/GtfsTest.java b/application/src/test/java/org/opentripplanner/GtfsTest.java index e5028525463..b4858617ff1 100644 --- a/application/src/test/java/org/opentripplanner/GtfsTest.java +++ b/application/src/test/java/org/opentripplanner/GtfsTest.java @@ -1,8 +1,6 @@ package org.opentripplanner; -import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.opentripplanner.street.model.StreetMode.NOT_SET; import static org.opentripplanner.street.model.StreetMode.WALK; @@ -22,7 +20,6 @@ import org.junit.jupiter.api.BeforeEach; import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.core.model.time.LocalDateRange; -import org.opentripplanner.ext.fares.service.gtfs.v1.DefaultFareService; import org.opentripplanner.gtfs.graphbuilder.GtfsBundle; import org.opentripplanner.gtfs.graphbuilder.GtfsBundleTestFactory; import org.opentripplanner.gtfs.graphbuilder.GtfsModule; @@ -32,13 +29,13 @@ import org.opentripplanner.routing.algorithm.raptoradapter.transit.RaptorTransitData; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitTuningParameters; import org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers.RaptorTransitDataMapper; +import org.opentripplanner.routing.api.RoutingService; import org.opentripplanner.routing.api.request.RequestModes; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.request.filter.SelectRequest; import org.opentripplanner.routing.api.request.request.filter.TransitFilterRequest; import org.opentripplanner.routing.api.response.RoutingResponse; import org.opentripplanner.routing.impl.TransitAlertServiceImpl; -import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.standalone.api.TestServerContext; import org.opentripplanner.standalone.config.RouterConfig; import org.opentripplanner.street.graph.Graph; @@ -47,6 +44,7 @@ import org.opentripplanner.transit.model.basic.MainAndSubMode; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.Deduplicator; +import org.opentripplanner.transit.service.DefaultTransitService; import org.opentripplanner.transit.service.SiteRepository; import org.opentripplanner.transit.service.TransitRepository; import org.opentripplanner.updater.GraphUpdaterManager; @@ -69,7 +67,7 @@ public abstract class GtfsTest { AlertsUpdateHandler alertsUpdateHandler; GtfsRealTimeTripUpdateAdapter tripUpdateAdapter; TransitAlertServiceImpl alertPatchServiceImpl; - public OtpServerRequestContext serverContext; + public RoutingService routingService; public abstract String getFeedName(); @@ -148,7 +146,7 @@ public Itinerary plan( }); // Route - RoutingResponse res = serverContext.routingService().route(builder.buildRequest()); + RoutingResponse res = routingService.route(builder.buildRequest()); // Assert itineraries List itineraries = res.getTripPlan().itineraries; @@ -165,8 +163,7 @@ public void validateLeg( long startTime, long endTime, String toStopId, - String fromStopId, - String alert + String fromStopId ) { assertEquals(startTime, leg.startTime().toInstant().toEpochMilli()); assertEquals(endTime, leg.endTime().toInstant().toEpochMilli()); @@ -178,13 +175,6 @@ public void validateLeg( } else { assertNull(leg.from().stop.getId()); } - if (alert != null) { - assertNotNull(leg.listStreetNotes()); - assertEquals(1, leg.listStreetNotes().size()); - assertEquals(alert, leg.listStreetNotes().iterator().next().note.toString()); - } else { - assertThat(leg.listStreetNotes()).isEmpty(); - } } @BeforeEach @@ -225,7 +215,7 @@ protected void setUp() throws Exception { org.opentripplanner.framework.transaction.internal.TransactionFactory.createRepositoryRegistry(); var timetableSnapshot = new org.opentripplanner.transit.repository.DefaultTimetableRepository( new RaptorTransitData(scheduledRaptorData), - transitRepository.copyTripCalendarForRealTimeUpdates() + transitRepository.getTripCalendar() ); var timetableHandle = registry.registerRepositorySnapshot( timetableSnapshot, @@ -275,18 +265,18 @@ protected void setUp() throws Exception { }) .get(); alertsUpdateHandler.update(feedMessage, null); - } catch (FileNotFoundException _) {} catch (Exception e) { + } catch (FileNotFoundException _) { + } catch (Exception e) { throw new RuntimeException(e); } - serverContext = TestServerContext.createServerContext( - graph, + var transitService = new DefaultTransitService( transitRepository, - transferRepository, - new DefaultFareService(), - timetableHandle, - registry, - null, - null + timetableHandle.repositorySnapshot(registry.scope()) + ); + routingService = TestServerContext.createRoutingService( + graph, + transitService, + transferRepository ); } } diff --git a/application/src/test/java/org/opentripplanner/_support/geometry/Polygons.java b/application/src/test/java/org/opentripplanner/_support/geometry/Polygons.java index 8ef229acd68..27609b45dc2 100644 --- a/application/src/test/java/org/opentripplanner/_support/geometry/Polygons.java +++ b/application/src/test/java/org/opentripplanner/_support/geometry/Polygons.java @@ -10,60 +10,52 @@ public class Polygons { private static final GeometryFactory FAC = GeometryUtils.getGeometryFactory(); - public static final Polygon BERLIN = FAC.createPolygon( - new Coordinate[] { - Coordinates.of(52.616841, 13.224692810), - Coordinates.of(52.616841, 13.646107734), - Coordinates.of(52.3915238, 13.646107734), - Coordinates.of(52.396421, 13.2268067), - Coordinates.of(52.616841, 13.224692810), - } - ); + public static final Polygon BERLIN = FAC.createPolygon(new Coordinate[] { + Coordinates.of(52.616841, 13.224692810), + Coordinates.of(52.616841, 13.646107734), + Coordinates.of(52.3915238, 13.646107734), + Coordinates.of(52.396421, 13.2268067), + Coordinates.of(52.616841, 13.224692810), + }); - public static final Polygon OSLO = FAC.createPolygon( - new Coordinate[] { - Coordinates.of(59.961055202323195, 10.62535658370308), - Coordinates.of(59.889009435700416, 10.62535658370308), - Coordinates.of(59.889009435700416, 10.849791142928694), - Coordinates.of(59.961055202323195, 10.849791142928694), - Coordinates.of(59.961055202323195, 10.62535658370308), - } - ); - public static final Polygon OSLO_FROGNER_PARK = FAC.createPolygon( - new Coordinate[] { - Coordinates.of(59.92939032560119, 10.69770054003061), - Coordinates.of(59.929138466684975, 10.695210909925208), - Coordinates.of(59.92745319808358, 10.692696865071184), - Coordinates.of(59.92709930323093, 10.693774304996225), - Coordinates.of(59.92745914988427, 10.69495957972947), - Coordinates.of(59.92736919590291, 10.697664535925895), - Coordinates.of(59.924837887427856, 10.697927604125255), - Coordinates.of(59.924447953413335, 10.697448767354985), - Coordinates.of(59.92378800804022, 10.697819761729818), - Coordinates.of(59.92329018587293, 10.699196446969069), - Coordinates.of(59.92347619027632, 10.700285749621997), - Coordinates.of(59.92272030268688, 10.704714696822037), - Coordinates.of(59.92597766029715, 10.71001707489603), - Coordinates.of(59.92676341291536, 10.707838597058043), - Coordinates.of(59.92790300889098, 10.708389137506913), - Coordinates.of(59.928376832499424, 10.707060536853078), - Coordinates.of(59.92831087551576, 10.705803789539402), - Coordinates.of(59.92953431964068, 10.706641515204467), - Coordinates.of(59.93046383654274, 10.70484606360543), - Coordinates.of(59.93008590667682, 10.701817874860211), - Coordinates.of(59.93028982601595, 10.700525251174469), - Coordinates.of(59.92939032560119, 10.69770054003061), - } - ); + public static final Polygon OSLO = FAC.createPolygon(new Coordinate[] { + Coordinates.of(59.961055202323195, 10.62535658370308), + Coordinates.of(59.889009435700416, 10.62535658370308), + Coordinates.of(59.889009435700416, 10.849791142928694), + Coordinates.of(59.961055202323195, 10.849791142928694), + Coordinates.of(59.961055202323195, 10.62535658370308), + }); + public static final Polygon OSLO_FROGNER_PARK = FAC.createPolygon(new Coordinate[] { + Coordinates.of(59.92939032560119, 10.69770054003061), + Coordinates.of(59.929138466684975, 10.695210909925208), + Coordinates.of(59.92745319808358, 10.692696865071184), + Coordinates.of(59.92709930323093, 10.693774304996225), + Coordinates.of(59.92745914988427, 10.69495957972947), + Coordinates.of(59.92736919590291, 10.697664535925895), + Coordinates.of(59.924837887427856, 10.697927604125255), + Coordinates.of(59.924447953413335, 10.697448767354985), + Coordinates.of(59.92378800804022, 10.697819761729818), + Coordinates.of(59.92329018587293, 10.699196446969069), + Coordinates.of(59.92347619027632, 10.700285749621997), + Coordinates.of(59.92272030268688, 10.704714696822037), + Coordinates.of(59.92597766029715, 10.71001707489603), + Coordinates.of(59.92676341291536, 10.707838597058043), + Coordinates.of(59.92790300889098, 10.708389137506913), + Coordinates.of(59.928376832499424, 10.707060536853078), + Coordinates.of(59.92831087551576, 10.705803789539402), + Coordinates.of(59.92953431964068, 10.706641515204467), + Coordinates.of(59.93046383654274, 10.70484606360543), + Coordinates.of(59.93008590667682, 10.701817874860211), + Coordinates.of(59.93028982601595, 10.700525251174469), + Coordinates.of(59.92939032560119, 10.69770054003061), + }); - public static final Polygon SELF_INTERSECTING = FAC.createPolygon( - new Coordinate[] { - Coordinates.of(1, 1), - Coordinates.of(1, 2), - Coordinates.of(1, 3), - Coordinates.of(1, 1), - } - ); + public static final Polygon SELF_INTERSECTING = FAC.createPolygon(new Coordinate[] { + Coordinates.of(1, 1), + Coordinates.of(1, 2), + Coordinates.of(1, 3), + Coordinates.of(1, 1), + }); public static org.geojson.Polygon toGeoJson(Polygon polygon) { var ret = new org.geojson.Polygon(); diff --git a/application/src/test/java/org/opentripplanner/api/parameter/QualifiedModeSetTest.java b/application/src/test/java/org/opentripplanner/api/parameter/QualifiedModeSetTest.java index 723a68560ef..5ac9554623d 100644 --- a/application/src/test/java/org/opentripplanner/api/parameter/QualifiedModeSetTest.java +++ b/application/src/test/java/org/opentripplanner/api/parameter/QualifiedModeSetTest.java @@ -85,9 +85,11 @@ void walkAndBikeRental() { @Test void transitAndBikeRental() { - QualifiedModeSet modeSet = new QualifiedModeSet( - new String[] { "WALK", "RAIL", "BICYCLE_RENT" } - ); + QualifiedModeSet modeSet = new QualifiedModeSet(new String[] { + "WALK", + "RAIL", + "BICYCLE_RENT", + }); assertEquals( Set.of( new QualifiedMode("WALK"), diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/GeoJsonScalarTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/GeoJsonScalarTest.java index be7081cdbf7..b703b694836 100644 --- a/application/src/test/java/org/opentripplanner/apis/gtfs/GeoJsonScalarTest.java +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/GeoJsonScalarTest.java @@ -13,14 +13,12 @@ class GeoJsonScalarTest { @Test void geoJson() throws JsonProcessingException { var gm = new GeometryFactory(); - var polygon = gm.createPolygon( - new Coordinate[] { - new Coordinate(0, 0), - new Coordinate(1, 1), - new Coordinate(2, 2), - new Coordinate(0, 0), - } - ); + var polygon = gm.createPolygon(new Coordinate[] { + new Coordinate(0, 0), + new Coordinate(1, 1), + new Coordinate(2, 2), + new Coordinate(0, 0), + }); var geoJson = GraphQLScalars.GEOJSON_SCALAR.getCoercing().serialize(polygon); var expected = ObjectMappers.ignoringExtraFields().readTree( diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java index cc61b6c13f3..44ab7c5caec 100644 --- a/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java @@ -108,7 +108,6 @@ import org.opentripplanner.transit.model._data.TransitRepositoryForTest; import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.model.basic.TransitMode; -import org.opentripplanner.transit.model.calendar.DefaultTripCalendars; import org.opentripplanner.transit.model.framework.AbstractBuilder; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.network.BikeAccess; @@ -184,7 +183,7 @@ class GraphQLIntegrationTest { private static final LocalDate SERVICE_DATE = LocalDate.of(2024, 1, 1); private static final int SERVICE_CODE = 0; - private static GraphQLRequestContext context; + private static GtfsGraphQLRequestContext context; private static final Deduplicator DEDUPLICATOR = new Deduplicator(); private static final VehicleParkingRepository PARKING_REPOSITORY = @@ -300,13 +299,13 @@ static void setup() { cal_id, List.of(firstDate, secondDate, SERVICE_DATE) ); - transitRepository.getServiceCodes().put(cal_id, SERVICE_CODE); + transitRepository.putServiceCode(cal_id, SERVICE_CODE); transitRepository.updateCalendarServiceData(calendarServiceData); transitRepository.index(); DefaultTimetableRepository timetableSnapshot = new DefaultTimetableRepository( RaptorTransitDataTestFactory.empty(), - new DefaultTripCalendars() + transitRepository.getTripCalendar() ); timetableSnapshot.update( RealTimeTripUpdate.of( @@ -473,6 +472,14 @@ public Collection listRoutes() { .withDescriptionText(I18NString.of("This station is currently closed")) .withEffect(AlertEffect.NO_SERVICE) .addEntity(stationEntitySelector) + // deliberately unsorted and with open bounds to test the sorting of the activity periods + .withCalendar( + AlertCalendar.of( + TimePeriod.of(ALERT_END_TIME, null), + TimePeriod.of(ALERT_START_TIME, ALERT_END_TIME), + TimePeriod.of(null, ALERT_START_TIME) + ) + ) .build(); // TODO - Use itineraryBuilder() here not build() and complete building the itinerary using @@ -552,7 +559,7 @@ public Collection listRoutes() { ); var routeRequest = RouteRequest.defaultValue(); - context = new GraphQLRequestContext( + context = new GtfsGraphQLRequestContext( new TestRoutingService(List.of(i1)), transitService, transitAlertService, diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/datafetchers/TripOnServiceDateImplTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/datafetchers/TripOnServiceDateImplTest.java index df4075c047b..38ad819abea 100644 --- a/application/src/test/java/org/opentripplanner/apis/gtfs/datafetchers/TripOnServiceDateImplTest.java +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/datafetchers/TripOnServiceDateImplTest.java @@ -14,7 +14,7 @@ import org.opentripplanner.transit.model.TransitTestEnvironment; import org.opentripplanner.transit.model.TransitTestEnvironmentBuilder; import org.opentripplanner.transit.model.TripInput; -import org.opentripplanner.transit.model.calendar.DefaultTripCalendars; +import org.opentripplanner.transit.model.calendar.TripCalendars; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.timetable.RealTimeTripUpdate; import org.opentripplanner.transit.model.timetable.Trip; @@ -125,7 +125,7 @@ private static TransitService transitServiceWithUpdate( var repo = env.transitRepository(); var snapshot = new DefaultTimetableRepository( repo.getRaptorTransitData(), - new DefaultTripCalendars() + TripCalendars.empty() ); snapshot.update(update); return new DefaultTransitService(repo, snapshot.commit()); diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/AlertsConnectionFilterMapperTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/AlertsConnectionFilterMapperTest.java new file mode 100644 index 00000000000..cd1b626f8bf --- /dev/null +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/AlertsConnectionFilterMapperTest.java @@ -0,0 +1,134 @@ +package org.opentripplanner.apis.gtfs.mapping; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.apis.support.InvalidInputException; +import org.opentripplanner.core.model.id.FeedScopedId; +import org.opentripplanner.routing.alertpatch.AlertCause; +import org.opentripplanner.routing.alertpatch.AlertEffect; +import org.opentripplanner.routing.alertpatch.AlertSeverity; +import org.opentripplanner.routing.alertpatch.EntitySelector; +import org.opentripplanner.routing.alertpatch.TransitAlert; +import org.opentripplanner.transit.model.filter.expr.Matcher; +import org.opentripplanner.transit.model.filter.transit.TransitAlertMatcherFactory; + +class AlertsConnectionFilterMapperTest { + + private static final FeedScopedId ROUTE_ID = new FeedScopedId("test", "foo"); + private static final FeedScopedId STOP_ID = new FeedScopedId("test", "bar"); + + private static final TransitAlert ROUTE_ALERT = TransitAlert.of(ROUTE_ID) + .addEntity(new EntitySelector.Route(ROUTE_ID)) + .withSeverity(AlertSeverity.SEVERE) + .withCause(AlertCause.ACCIDENT) + .withEffect(AlertEffect.REDUCED_SERVICE) + .build(); + private static final TransitAlert STOP_ALERT = TransitAlert.of(STOP_ID) + .addEntity(new EntitySelector.Stop(STOP_ID)) + .withSeverity(AlertSeverity.INFO) + .withCause(AlertCause.UNKNOWN_CAUSE) + .withEffect(AlertEffect.DETOUR) + .build(); + + @Test + void emptyFiltersProduceNoFilters() { + assertTrue(AlertsConnectionFilterMapper.map(null).filters().isEmpty()); + assertTrue(AlertsConnectionFilterMapper.map(List.of()).filters().isEmpty()); + } + + @Test + void includeMatchesCause() { + var matcher = matcher(filter("include", Map.of("causes", List.of("ACCIDENT")))); + assertTrue(matcher.match(ROUTE_ALERT)); + assertFalse(matcher.match(STOP_ALERT)); + } + + @Test + void excludeRejectsEffect() { + var matcher = matcher(filter("exclude", Map.of("effects", List.of("DETOUR")))); + assertTrue(matcher.match(ROUTE_ALERT)); + assertFalse(matcher.match(STOP_ALERT)); + } + + @Test + void severityIsExpandedToInternalValues() { + var matcher = matcher(filter("include", Map.of("severityLevels", List.of("SEVERE")))); + assertTrue(matcher.match(ROUTE_ALERT)); + assertFalse(matcher.match(STOP_ALERT)); + } + + /** + * Selectors within a single include list are combined with OR semantics, so both alerts match + * even though neither selector matches both. + */ + @Test + void selectorsAreCombinedWithOr() { + var matcher = matcher( + filter("include", Map.of("causes", List.of("ACCIDENT")), Map.of("effects", List.of("DETOUR"))) + ); + assertTrue(matcher.match(ROUTE_ALERT)); + assertTrue(matcher.match(STOP_ALERT)); + } + + /** + * Dimensions within a single selector are combined with AND semantics. + */ + @Test + void dimensionsOfASelectorAreCombinedWithAnd() { + var matcher = matcher( + filter("include", Map.of("causes", List.of("ACCIDENT"), "effects", List.of("DETOUR"))) + ); + assertFalse(matcher.match(ROUTE_ALERT)); + assertFalse(matcher.match(STOP_ALERT)); + } + + @Test + void emptySelectorListIsRejected() { + assertThrows(IllegalArgumentException.class, () -> + AlertsConnectionFilterMapper.map(List.of(filter("include"))) + ); + } + + @Test + void emptyDimensionListIsRejected() { + assertThrows(InvalidInputException.class, () -> + AlertsConnectionFilterMapper.map(List.of(filter("include", Map.of("causes", List.of())))) + ); + } + + @Test + void nullValueInDimensionListIsRejected() { + assertThrows(InvalidInputException.class, () -> + AlertsConnectionFilterMapper.map( + List.of(filter("include", mapOfNullableList("feeds", "test", null))) + ) + ); + } + + private static GraphQLTypes.GraphQLAlertsFilterInput filter( + String direction, + Map... selectors + ) { + return new GraphQLTypes.GraphQLAlertsFilterInput( + Map.of(direction, Arrays.stream(selectors).toList()) + ); + } + + private static Map mapOfNullableList(String key, String... values) { + var map = new HashMap(); + map.put(key, Arrays.asList(values)); + return map; + } + + private static Matcher matcher(GraphQLTypes.GraphQLAlertsFilterInput filter) { + return TransitAlertMatcherFactory.of(AlertsConnectionFilterMapper.map(List.of(filter))); + } +} diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/CanceledTripsFilterMapperTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/CanceledTripsFilterMapperTest.java index dee76691919..61f90a021a8 100644 --- a/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/CanceledTripsFilterMapperTest.java +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/CanceledTripsFilterMapperTest.java @@ -9,6 +9,7 @@ import graphql.schema.DataFetchingEnvironment; import graphql.schema.DataFetchingEnvironmentImpl; import java.time.LocalDate; +import java.time.OffsetDateTime; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -17,6 +18,7 @@ import org.opentripplanner.apis.support.InvalidInputException; import org.opentripplanner.apis.support.graphql.DataFetchingSupport; import org.opentripplanner.core.model.time.LocalDateRange; +import org.opentripplanner.core.model.time.TimePeriod; import org.opentripplanner.transit.model.basic.MainAndSubMode; import org.opentripplanner.transit.model.basic.TransitMode; @@ -218,6 +220,95 @@ void testEmptyServiceDateRanges() { ); } + @Test + void testIncludeWithRunningTimeRanges() { + var start = OffsetDateTime.parse("2026-06-01T10:00:00+02:00"); + var end = OffsetDateTime.parse("2026-06-01T12:00:00+02:00"); + Map args = Map.of( + "filters", + List.of( + Map.of( + "include", + List.of(Map.of("runningTimeRanges", List.of(Map.of("start", start, "end", end)))) + ) + ) + ); + + var request = CanceledTripsFilterMapper.mapToTripOnServiceDateRequest(getEnvironment(args)); + assertThat(request.filters()).hasSize(1); + var include = request.filters().getFirst().select().getFirst(); + assertThat(include.runningTimePeriods().get()).containsExactly( + TimePeriod.of(start.toInstant(), end.toInstant()) + ); + } + + @Test + void testExcludeWithOpenEndedRunningTimeRange() { + var start = OffsetDateTime.parse("2026-07-01T00:00:00Z"); + Map args = Map.of( + "filters", + List.of( + Map.of("exclude", List.of(Map.of("runningTimeRanges", List.of(Map.of("start", start))))) + ) + ); + + var request = CanceledTripsFilterMapper.mapToTripOnServiceDateRequest(getEnvironment(args)); + assertThat(request.filters()).hasSize(1); + var exclude = request.filters().getFirst().not().getFirst(); + assertThat(exclude.runningTimePeriods().get()).containsExactly( + TimePeriod.of(start.toInstant(), null) + ); + } + + @Test + void testEmptyRunningTimeRanges() { + Map args = Map.of( + "filters", + List.of(Map.of("include", List.of(Map.of("runningTimeRanges", List.of())))) + ); + var environment = getEnvironment(args); + var exception = assertThrows(InvalidInputException.class, () -> + CanceledTripsFilterMapper.mapToTripOnServiceDateRequest(environment) + ); + assertEquals( + "Time range filter 'filters.*.runningTimeRanges' must be either null or have at least one entry.", + exception.getMessage() + ); + } + + @Test + void testRunningTimeRangeWithStartAfterEnd() { + Map args = Map.of( + "filters", + List.of( + Map.of( + "include", + List.of( + Map.of( + "runningTimeRanges", + List.of( + Map.of( + "start", + OffsetDateTime.parse("2026-06-02T10:00:00Z"), + "end", + OffsetDateTime.parse("2026-06-01T10:00:00Z") + ) + ) + ) + ) + ) + ) + ); + var environment = getEnvironment(args); + var exception = assertThrows(InvalidInputException.class, () -> + CanceledTripsFilterMapper.mapToTripOnServiceDateRequest(environment) + ); + assertEquals( + "The start of the time range 'filters.*.runningTimeRanges' must not be after its end.", + exception.getMessage() + ); + } + private DataFetchingEnvironment getEnvironment(Map arguments) { var executionContext = DataFetchingSupport.executionContext(); return DataFetchingEnvironmentImpl.newDataFetchingEnvironment(executionContext) diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapperTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapperTest.java deleted file mode 100644 index 0f129d5e611..00000000000 --- a/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapperTest.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.opentripplanner.apis.gtfs.mapping; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.time.Instant; -import java.util.Collections; -import java.util.Date; -import java.util.Locale; -import java.util.Optional; -import org.junit.jupiter.api.Test; -import org.opentripplanner.routing.alertpatch.TransitAlert; -import org.opentripplanner.street.model.note.StreetNote; - -class StreetNoteMapperTest { - - static final String TEST_STREET_NOTE_HEADER = "Test Street Note"; - static final String TEST_STREET_NOTE_DESCRIPTION = "Test Street Note Description"; - static final String TEST_STREET_NOTE_URL = "http://www.example.com/test-note"; - static final Date START_DATE = new Date(); - static final Instant START_INSTANCE = START_DATE.toInstant(); - static final Instant END_INSTANCE = START_INSTANCE.plusSeconds(3600); - - @Test - void mapRegularAlert() { - var note = note(); - TransitAlert alert = StreetNoteMapper.mapStreetNoteToAlert(note); - assertEquals(TEST_STREET_NOTE_HEADER, alert.headerText().get().toString(Locale.ROOT)); - assertEquals(TEST_STREET_NOTE_DESCRIPTION, alert.descriptionText().get().toString(Locale.ROOT)); - assertEquals(TEST_STREET_NOTE_URL, alert.url().get().toString(Locale.ROOT)); - assertEquals(START_INSTANCE, alert.getEffectiveStartDate()); - assertEquals(END_INSTANCE, alert.getEffectiveEndDate()); - } - - @Test - void mapNullUrl() { - var note = note(); - note.url = null; - TransitAlert alert = StreetNoteMapper.mapStreetNoteToAlert(note); - assertEquals(Optional.empty(), alert.url()); - } - - @Test - void noTime() { - var note = note(); - note.effectiveStartDate = null; - note.effectiveEndDate = null; - TransitAlert alert = StreetNoteMapper.mapStreetNoteToAlert(note); - assertEquals(Collections.emptyList(), alert.calendar().timePeriods()); - } - - private static StreetNote note() { - StreetNote note = new StreetNote(TEST_STREET_NOTE_HEADER); - note.descriptionText = locale -> TEST_STREET_NOTE_DESCRIPTION; - note.url = TEST_STREET_NOTE_URL; - note.effectiveStartDate = START_DATE; - note.effectiveEndDate = Date.from(END_INSTANCE); - return note; - } -} diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImplTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/AlertsFilterTest.java similarity index 88% rename from application/src/test/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImplTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/AlertsFilterTest.java index 12dc429b3a9..8b94a4f69ba 100644 --- a/application/src/test/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImplTest.java +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/AlertsFilterTest.java @@ -1,6 +1,7 @@ -package org.opentripplanner.apis.gtfs.datafetchers; +package org.opentripplanner.apis.gtfs.mapping.routerequest; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.apis.gtfs.support.filter.AlertsFilter.filterAlerts; import java.util.List; import java.util.Map; @@ -15,7 +16,7 @@ import org.opentripplanner.routing.alertpatch.EntitySelector; import org.opentripplanner.routing.alertpatch.TransitAlert; -public class QueryTypeImplTest { +class AlertsFilterTest { private static FeedScopedId ROUTE_ID = new FeedScopedId("test", "foo"); @@ -52,7 +53,7 @@ public void testFilterAlertsWithNoFilterArgs() { var queryTypeAlertsArgs = new GraphQLTypes.GraphQLQueryTypeAlertsArgs(args); - var filteredAlerts = QueryTypeImpl.filterAlerts(alerts, queryTypeAlertsArgs); + var filteredAlerts = filterAlerts(alerts, queryTypeAlertsArgs); assertEquals(2, filteredAlerts.size()); } @@ -70,7 +71,7 @@ public void testFilterAlertsSeverity() { var queryTypeAlertsArgs = new GraphQLTypes.GraphQLQueryTypeAlertsArgs(args); - var filteredAlerts = QueryTypeImpl.filterAlerts(alerts, queryTypeAlertsArgs); + var filteredAlerts = filterAlerts(alerts, queryTypeAlertsArgs); assertEquals(1, filteredAlerts.size()); assertEquals(AlertSeverity.SEVERE, filteredAlerts.get(0).severity()); } @@ -89,7 +90,7 @@ public void testFilterAlertsCause() { var queryTypeAlertsArgs = new GraphQLTypes.GraphQLQueryTypeAlertsArgs(args); - var filteredAlerts = QueryTypeImpl.filterAlerts(alerts, queryTypeAlertsArgs); + var filteredAlerts = filterAlerts(alerts, queryTypeAlertsArgs); assertEquals(1, filteredAlerts.size()); assertEquals(AlertCause.UNKNOWN_CAUSE, filteredAlerts.get(0).cause()); } @@ -108,7 +109,7 @@ public void testFilterAlertsEffect() { var queryTypeAlertsArgs = new GraphQLTypes.GraphQLQueryTypeAlertsArgs(args); - var filteredAlerts = QueryTypeImpl.filterAlerts(alerts, queryTypeAlertsArgs); + var filteredAlerts = filterAlerts(alerts, queryTypeAlertsArgs); assertEquals(1, filteredAlerts.size()); assertEquals(AlertEffect.REDUCED_SERVICE, filteredAlerts.get(0).effect()); } @@ -141,7 +142,7 @@ public void testFilterAlertsMultipleArgs() { var queryTypeAlertsArgs = new GraphQLTypes.GraphQLQueryTypeAlertsArgs(args); - var filteredAlerts = QueryTypeImpl.filterAlerts(alerts, queryTypeAlertsArgs); + var filteredAlerts = filterAlerts(alerts, queryTypeAlertsArgs); assertEquals(1, filteredAlerts.size()); assertEquals(AlertSeverity.INFO, filteredAlerts.get(0).severity()); assertEquals(AlertCause.UNKNOWN_CAUSE, filteredAlerts.get(0).cause()); @@ -154,7 +155,7 @@ public void testFilterAlertsRoute() { var queryTypeAlertsArgs = new GraphQLTypes.GraphQLQueryTypeAlertsArgs(args); - var filteredAlerts = QueryTypeImpl.filterAlerts(alerts, queryTypeAlertsArgs); + var filteredAlerts = filterAlerts(alerts, queryTypeAlertsArgs); assertEquals(1, filteredAlerts.size()); assertEquals(ROUTE_ID, filteredAlerts.get(0).getId()); } @@ -165,7 +166,7 @@ public void testFilterAlertsStop() { var queryTypeAlertsArgs = new GraphQLTypes.GraphQLQueryTypeAlertsArgs(args); - var filteredAlerts = QueryTypeImpl.filterAlerts(alerts, queryTypeAlertsArgs); + var filteredAlerts = filterAlerts(alerts, queryTypeAlertsArgs); assertEquals(1, filteredAlerts.size()); assertEquals(STOP_ID, filteredAlerts.get(0).getId()); } diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapperTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapperTest.java index fa34ad0bef7..8cb5e525436 100644 --- a/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapperTest.java +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapperTest.java @@ -25,7 +25,7 @@ import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; import org.opentripplanner._support.time.ZoneIds; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.SchemaFactory; import org.opentripplanner.apis.gtfs.TestRoutingService; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; @@ -59,7 +59,7 @@ class LegacyRouteRequestMapperTest implements PlanTestConstants { - private static final GraphQLRequestContext CONTEXT; + private static final GtfsGraphQLRequestContext CONTEXT; private static final FeedScopedId TRIP_ID_1 = id("t1"); private static final FeedScopedId TRIP_ID_2 = id("t2"); @@ -85,7 +85,7 @@ class LegacyRouteRequestMapperTest implements PlanTestConstants { return Optional.ofNullable(group).map(locationsGroup -> locationsGroup.getCoordinate()); } ); - CONTEXT = new GraphQLRequestContext( + CONTEXT = new GtfsGraphQLRequestContext( new TestRoutingService(List.of()), transitService, new TransitAlertServiceImpl(), diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/_RouteRequestTestContext.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/_RouteRequestTestContext.java index 5f9215edc20..34c88970dc7 100644 --- a/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/_RouteRequestTestContext.java +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/_RouteRequestTestContext.java @@ -12,7 +12,7 @@ import java.util.Optional; import org.locationtech.jts.geom.Coordinate; import org.opentripplanner._support.time.ZoneIds; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext; import org.opentripplanner.apis.gtfs.SchemaFactory; import org.opentripplanner.apis.gtfs.TestRoutingService; import org.opentripplanner.apis.support.graphql.DataFetchingSupport; @@ -54,7 +54,7 @@ class _RouteRequestTestContext { ) ); - private final GraphQLRequestContext context; + private final GtfsGraphQLRequestContext context; private final Locale locale; public _RouteRequestTestContext(Locale locale) { @@ -77,7 +77,7 @@ public _RouteRequestTestContext(Locale locale) { return Optional.ofNullable(group).map(locationsGroup -> locationsGroup.getCoordinate()); } ); - this.context = new GraphQLRequestContext( + this.context = new GtfsGraphQLRequestContext( new TestRoutingService(List.of()), transitService, new TransitAlertServiceImpl(), @@ -106,7 +106,7 @@ static _RouteRequestTestContext of(Locale locale) { return new _RouteRequestTestContext(locale); } - public GraphQLRequestContext context() { + public GtfsGraphQLRequestContext context() { return context; } diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/model/OffsetDateTimeRangeTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/model/OffsetDateTimeRangeTest.java new file mode 100644 index 00000000000..05e2a2443de --- /dev/null +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/model/OffsetDateTimeRangeTest.java @@ -0,0 +1,52 @@ +package org.opentripplanner.apis.gtfs.model; + +import static com.google.common.truth.Truth.assertThat; + +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.opentripplanner.core.model.time.TimePeriod; + +class OffsetDateTimeRangeTest { + + private static final ZoneId ZONE_ID = ZoneId.of("Europe/Berlin"); + private static final Instant START = OffsetDateTime.parse( + "2023-02-15T12:03:28+01:00" + ).toInstant(); + private static final Instant END = OffsetDateTime.parse("2023-02-16T12:03:28+01:00").toInstant(); + + @Test + void convertBoundedPeriod() { + var subject = OffsetDateTimeRange.of(TimePeriod.of(START, END), ZONE_ID); + + assertThat(subject.start()).isEqualTo(OffsetDateTime.parse("2023-02-15T12:03:28+01:00")); + assertThat(subject.end()).isEqualTo(OffsetDateTime.parse("2023-02-16T12:03:28+01:00")); + } + + @Test + void convertUnboundedPeriod() { + var subject = OffsetDateTimeRange.of(TimePeriod.ofUnbounded(), ZONE_ID); + + assertThat(subject.start()).isNull(); + assertThat(subject.end()).isNull(); + } + + @Test + void sortChronologically() { + var unboundedStart = OffsetDateTimeRange.of(TimePeriod.of(null, START), ZONE_ID); + var bounded = OffsetDateTimeRange.of(TimePeriod.of(START, END), ZONE_ID); + var unboundedEndFromStart = OffsetDateTimeRange.of(TimePeriod.of(START, null), ZONE_ID); + var unboundedEnd = OffsetDateTimeRange.of(TimePeriod.of(END, null), ZONE_ID); + + var sorted = List.of(unboundedEnd, bounded, unboundedEndFromStart, unboundedStart) + .stream() + .sorted(OffsetDateTimeRange.CHRONOLOGICAL_ORDER) + .toList(); + + assertThat(sorted) + .containsExactly(unboundedStart, bounded, unboundedEndFromStart, unboundedEnd) + .inOrder(); + } +} diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/service/ApiTransitServiceTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/service/ApiTransitServiceTest.java index 31bb843a5d6..42696503132 100644 --- a/application/src/test/java/org/opentripplanner/apis/gtfs/service/ApiTransitServiceTest.java +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/service/ApiTransitServiceTest.java @@ -17,6 +17,7 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner.core.model.time.LocalDateRange; +import org.opentripplanner.core.model.time.TimePeriod; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.TripTimeOnDate; import org.opentripplanner.model.plan.leg.ScheduledTransitLegBuilder; @@ -185,6 +186,7 @@ void canceledStopCalls() { new ApiTransitService(env.transitService()).findCanceledStopCalls( STOP_B, SERVICE_DATE_RANGES, + null, ArrivalDeparture.BOTH ) ).isEmpty(); @@ -193,7 +195,12 @@ void canceledStopCalls() { assertSuccess(rt.applyTripUpdate(update)); var service = new ApiTransitService(env.transitService()); - var calls = service.findCanceledStopCalls(STOP_B, SERVICE_DATE_RANGES, ArrivalDeparture.BOTH); + var calls = service.findCanceledStopCalls( + STOP_B, + SERVICE_DATE_RANGES, + null, + ArrivalDeparture.BOTH + ); assertThat(calls).hasSize(1); var call = calls.getFirst(); assertEquals(TRIP_1_ID, call.stopCall().getTrip().getId().getId()); @@ -218,6 +225,7 @@ void skippedStopVisitsAreIncluded() { var skippedCalls = service.findCanceledStopCalls( STOP_B, SERVICE_DATE_RANGES, + null, ArrivalDeparture.BOTH ); assertThat(skippedCalls).hasSize(1); @@ -227,7 +235,7 @@ void skippedStopVisitsAreIncluded() { // Stops that are not skipped and whose trip is not canceled are not returned assertThat( - service.findCanceledStopCalls(STOP_A, SERVICE_DATE_RANGES, ArrivalDeparture.BOTH) + service.findCanceledStopCalls(STOP_A, SERVICE_DATE_RANGES, null, ArrivalDeparture.BOTH) ).isEmpty(); } @@ -246,16 +254,16 @@ void canceledStopCallsFilteredByServiceDate() { LocalDateRange.ofExclusiveEnd(SERVICE_DATE.plusDays(1), SERVICE_DATE.plusDays(2)) ); assertThat( - service.findCanceledStopCalls(STOP_B, outsideRange, ArrivalDeparture.BOTH) + service.findCanceledStopCalls(STOP_B, outsideRange, null, ArrivalDeparture.BOTH) ).isEmpty(); // Range that includes the service date returns the canceled call var insideRange = List.of( LocalDateRange.ofExclusiveEnd(SERVICE_DATE, SERVICE_DATE.plusDays(1)) ); - assertThat(service.findCanceledStopCalls(STOP_B, insideRange, ArrivalDeparture.BOTH)).hasSize( - 1 - ); + assertThat( + service.findCanceledStopCalls(STOP_B, insideRange, null, ArrivalDeparture.BOTH) + ).hasSize(1); } @Test @@ -275,10 +283,54 @@ void canceledStopCallsOmitNonPickups() { // The drop-off-only visit at STOP_C is returned with BOTH but omitted when only departures // (pickups) are requested. assertThat( - service.findCanceledStopCalls(STOP_C, SERVICE_DATE_RANGES, ArrivalDeparture.BOTH) + service.findCanceledStopCalls(STOP_C, SERVICE_DATE_RANGES, null, ArrivalDeparture.BOTH) ).hasSize(1); assertThat( - service.findCanceledStopCalls(STOP_C, SERVICE_DATE_RANGES, ArrivalDeparture.DEPARTURES) + service.findCanceledStopCalls(STOP_C, SERVICE_DATE_RANGES, null, ArrivalDeparture.DEPARTURES) + ).isEmpty(); + } + + @Test + void canceledStopCallsFilteredByCallTime() { + var env = envBuilder.addTrip(TRIP1_INPUT).build(); + var rt = GtfsRtTestHelper.of(env); + + var update = rt.tripUpdate(TRIP_1_ID, CANCELED).build(); + assertSuccess(rt.applyTripUpdate(update)); + + var service = new ApiTransitService(env.transitService()); + + // The vehicle visits STOP_B at 12:30 on the service date + var overlapping = List.of( + TimePeriod.of(instant(LocalTime.of(12, 15)), instant(LocalTime.of(12, 45))) + ); + assertThat( + service.findCanceledStopCalls(STOP_B, SERVICE_DATE_RANGES, overlapping, ArrivalDeparture.BOTH) + ).hasSize(1); + + // The trip runs from 12:00 until 13:00 but the vehicle does not visit STOP_B during this range + var duringTripButNotAtStop = List.of( + TimePeriod.of(instant(LocalTime.of(12, 45)), instant(LocalTime.of(13, 0))) + ); + assertThat( + service.findCanceledStopCalls( + STOP_B, + SERVICE_DATE_RANGES, + duringTripButNotAtStop, + ArrivalDeparture.BOTH + ) + ).isEmpty(); + + var notOverlapping = List.of( + TimePeriod.of(instant(LocalTime.of(13, 30)), instant(LocalTime.of(14, 0))) + ); + assertThat( + service.findCanceledStopCalls( + STOP_B, + SERVICE_DATE_RANGES, + notOverlapping, + ArrivalDeparture.BOTH + ) ).isEmpty(); } @@ -333,4 +385,8 @@ void findTripOnServiceDateReturnsRealTripOnServiceDate() { private static GtfsRealtime.TripUpdate skipSecondStop(TripUpdateBuilder builder) { return builder.addSkippedStop(1).build(); } + + private static Instant instant(LocalTime time) { + return SERVICE_DATE.atTime(time).atZone(TIME_ZONE).toInstant(); + } } diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/support/sort/AlertsConnectionOrderingTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/support/sort/AlertsConnectionOrderingTest.java new file mode 100644 index 00000000000..53eb40b6f8f --- /dev/null +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/support/sort/AlertsConnectionOrderingTest.java @@ -0,0 +1,95 @@ +package org.opentripplanner.apis.gtfs.support.sort; + +import static com.google.common.truth.Truth.assertThat; + +import java.time.Instant; +import java.util.List; +import javax.annotation.Nullable; +import org.junit.jupiter.api.Test; +import org.opentripplanner.core.model.id.FeedScopedId; +import org.opentripplanner.core.model.time.TimePeriod; +import org.opentripplanner.routing.alertpatch.AlertCalendar; +import org.opentripplanner.routing.alertpatch.AlertSeverity; +import org.opentripplanner.routing.alertpatch.TransitAlert; + +class AlertsConnectionOrderingTest { + + private static final Instant EARLY = Instant.parse("2025-01-01T00:00:00Z"); + private static final Instant LATE = Instant.parse("2025-06-01T00:00:00Z"); + + @Test + void sortsBySeverityDescending() { + var info = alert("info", AlertSeverity.INFO, EARLY); + var severe = alert("severe", AlertSeverity.SEVERE, EARLY); + var verySevere = alert("very-severe", AlertSeverity.VERY_SEVERE, EARLY); + + assertThat(AlertsConnectionOrdering.sort(List.of(info, verySevere, severe))) + .containsExactly(verySevere, severe, info) + .inOrder(); + } + + @Test + void sortsByEffectiveStartAscendingWithinSeverity() { + var late = alert("late", AlertSeverity.WARNING, LATE); + var early = alert("early", AlertSeverity.WARNING, EARLY); + + assertThat(AlertsConnectionOrdering.sort(List.of(late, early))) + .containsExactly(early, late) + .inOrder(); + } + + @Test + void alertWithoutSeverityIsTreatedAsUnknown() { + var noSeverity = alert("no-severity", null, EARLY); + var unknown = alert("unknown", AlertSeverity.UNKNOWN_SEVERITY, LATE); + var info = alert("info", AlertSeverity.INFO, EARLY); + var slight = alert("slight", AlertSeverity.SLIGHT, EARLY); + + // unknown severity sorts between SLIGHT and INFO, according to the enum declaration order + assertThat(AlertsConnectionOrdering.sort(List.of(info, unknown, slight, noSeverity))) + .containsExactly(slight, noSeverity, unknown, info) + .inOrder(); + } + + @Test + void sortsByIdAsTiebreaker() { + var b = alert("b", AlertSeverity.WARNING, EARLY); + var a = alert("a", AlertSeverity.WARNING, EARLY); + var c = alert("c", AlertSeverity.WARNING, EARLY); + + assertThat(AlertsConnectionOrdering.sort(List.of(c, b, a))) + .containsExactly(a, b, c) + .inOrder(); + } + + @Test + void orderIsStableAcrossCalls() { + var alerts = List.of( + alert("b", AlertSeverity.WARNING, EARLY), + alert("a", AlertSeverity.WARNING, EARLY), + alert("c", AlertSeverity.SEVERE, LATE) + ); + + var first = AlertsConnectionOrdering.sort(alerts); + var second = AlertsConnectionOrdering.sort( + List.of(alerts.get(2), alerts.get(0), alerts.get(1)) + ); + + assertThat(second).containsExactlyElementsIn(first).inOrder(); + } + + private static TransitAlert alert( + String id, + @Nullable AlertSeverity severity, + Instant effectiveStart + ) { + return TransitAlert.of(id(id)) + .withSeverity(severity) + .withCalendar(AlertCalendar.of(TimePeriod.of(effectiveStart, null))) + .build(); + } + + private static FeedScopedId id(String id) { + return new FeedScopedId("F", id); + } +} diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/support/time/OffsetDateTimeRangeUtilTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/support/time/OffsetDateTimeRangeUtilTest.java new file mode 100644 index 00000000000..73e486ca287 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/support/time/OffsetDateTimeRangeUtilTest.java @@ -0,0 +1,64 @@ +package org.opentripplanner.apis.gtfs.support.time; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.time.OffsetDateTime; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.apis.support.InvalidInputException; +import org.opentripplanner.core.model.time.TimePeriod; + +class OffsetDateTimeRangeUtilTest { + + private static final OffsetDateTime START = OffsetDateTime.parse("2026-06-01T10:00:00+02:00"); + private static final OffsetDateTime END = OffsetDateTime.parse("2026-06-01T12:00:00+02:00"); + private static final String FIELD = "runningTimeRanges"; + + @Test + void nullRangesAreNotMapped() { + assertNull(OffsetDateTimeRangeUtil.mapRanges(null, FIELD)); + } + + @Test + void mapRanges() { + var ranges = List.of( + new GraphQLTypes.GraphQLOffsetDateTimeRangeInput(Map.of("start", START, "end", END)), + new GraphQLTypes.GraphQLOffsetDateTimeRangeInput(Map.of("start", START)), + new GraphQLTypes.GraphQLOffsetDateTimeRangeInput(Map.of("end", END)), + new GraphQLTypes.GraphQLOffsetDateTimeRangeInput(Map.of()) + ); + + assertThat(OffsetDateTimeRangeUtil.mapRanges(ranges, FIELD)) + .containsExactly( + TimePeriod.of(START.toInstant(), END.toInstant()), + TimePeriod.of(START.toInstant(), null), + TimePeriod.of(null, END.toInstant()), + TimePeriod.ofUnbounded() + ) + .inOrder(); + } + + @Test + void emptyRangesAreForbidden() { + var exception = assertThrows(InvalidInputException.class, () -> + OffsetDateTimeRangeUtil.mapRanges(List.of(), FIELD) + ); + assertThat(exception.getMessage()).isEqualTo( + "Time range filter 'runningTimeRanges' must be either null or have at least one entry." + ); + } + + @Test + void startAfterEndIsForbidden() { + var exception = assertThrows(InvalidInputException.class, () -> + OffsetDateTimeRangeUtil.mapRange(END, START, FIELD) + ); + assertThat(exception.getMessage()).isEqualTo( + "The start of the time range 'runningTimeRanges' must not be after its end." + ); + } +} diff --git a/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java index da83a74b8de..591de412356 100644 --- a/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java +++ b/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java @@ -28,7 +28,6 @@ import org.opentripplanner.apis.support.InvalidInputException; import org.opentripplanner.apis.support.graphql.DataFetchingSupport; import org.opentripplanner.apis.transmodel.TransmodelRequestContext; -import org.opentripplanner.ext.fares.service.gtfs.v1.DefaultFareService; import org.opentripplanner.model.calendar.CalendarServiceData; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; @@ -39,6 +38,7 @@ import org.opentripplanner.routing.api.request.preference.StreetPreferences; import org.opentripplanner.routing.api.request.preference.TimeSlopeSafetyTriangle; import org.opentripplanner.routing.api.request.via.ViaLocation; +import org.opentripplanner.routing.linking.VertexLinkerTestFactory; import org.opentripplanner.standalone.api.TestServerContext; import org.opentripplanner.street.graph.Graph; import org.opentripplanner.street.model.StreetMode; @@ -104,7 +104,7 @@ public class TripRequestMapperTest implements PlanTestConstants { .getTripTimes() .getFirst() .getServiceCode(); - TIMETABLE_REPOSITORY.getServiceCodes().put(pattern.getId(), serviceCode); + TIMETABLE_REPOSITORY.putServiceCode(pattern.getId(), serviceCode); calendarServiceData.putServiceDatesForServiceId(pattern.getId(), List.of(serviceDate)); }); @@ -128,20 +128,25 @@ void setup() { ) .buildDefault(); - var otpServerRequestContext = TestServerContext.createServerContext( - GRAPH, + var transitService = TestServerContext.createTransitService( TIMETABLE_REPOSITORY, - TRANSFER_REPOSITORY, - new DefaultFareService(), - defaultRequest, - null + TRANSFER_REPOSITORY ); + var vertexLinker = VertexLinkerTestFactory.of(GRAPH); context = new TransmodelRequestContext( - otpServerRequestContext, - otpServerRequestContext.routingService(), - otpServerRequestContext.transitService(), - otpServerRequestContext.empiricalDelayService() + TestServerContext.createRoutingService(GRAPH, transitService, TRANSFER_REPOSITORY), + transitService, + null, + null, + defaultRequest, + TestServerContext.createVehicleRentalService(), + TestServerContext.createVehicleParkingService(), + GRAPH, + TransferServiceTestFactory.transferService(TRANSFER_REPOSITORY), + TestServerContext.createStreetDetailsService(), + TestServerContext.createLinkingContextFactory(GRAPH, vertexLinker, transitService), + TestServerContext.createStreetLimitationParametersService() ); } diff --git a/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripViaLocationMapperTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripViaLocationMapperTest.java index b838f7ff4ac..e02ba683ce3 100644 --- a/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripViaLocationMapperTest.java +++ b/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripViaLocationMapperTest.java @@ -31,9 +31,9 @@ class TripViaLocationMapperTest { private static final List LIST_IDS_INPUT = List.of("F:ID1", "F:ID2"); private static final String EXPECTED_IDS_AS_STRING = "[F:ID1, F:ID2]"; private static final String REASON_EMPTY_IDS_ALLOWED_PASS_THROUGH = """ - Unfortunately the 'placeIds' is not required. Making it required would be a breaking change, - so wee just ignore it." - """; + Unfortunately the 'placeIds' is not required. Making it required would be a breaking change, + so wee just ignore it." + """; private static final TripViaLocationMapper MAPPER = new TripViaLocationMapper( new DefaultFeedIdMapper() diff --git a/application/src/test/java/org/opentripplanner/apis/transmodel/model/EnumTypesTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/model/EnumTypesTest.java index f20f125b8f9..e1794802fe7 100644 --- a/application/src/test/java/org/opentripplanner/apis/transmodel/model/EnumTypesTest.java +++ b/application/src/test/java/org/opentripplanner/apis/transmodel/model/EnumTypesTest.java @@ -3,12 +3,16 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.opentripplanner.apis.transmodel.model.EnumTypes.LEG_MODE; import static org.opentripplanner.apis.transmodel.model.EnumTypes.RELATIVE_DIRECTION; import static org.opentripplanner.apis.transmodel.model.EnumTypes.ROUTING_ERROR_CODE; +import static org.opentripplanner.apis.transmodel.model.EnumTypes.TRANSPORT_MODE; import static org.opentripplanner.apis.transmodel.model.EnumTypes.map; import graphql.GraphQLContext; +import graphql.schema.GraphQLEnumType; import java.util.EnumSet; import java.util.List; import java.util.Locale; @@ -19,6 +23,7 @@ import org.opentripplanner.core.model.doc.DocumentedEnum; import org.opentripplanner.model.plan.walkstep.RelativeDirection; import org.opentripplanner.routing.api.response.RoutingErrorCode; +import org.opentripplanner.transit.model.basic.TransitMode; class EnumTypesTest { @@ -105,6 +110,24 @@ void assertAllRoutingErrorCodesAreMapped() { assertEquals(expected, values); } + /** + * Carpool lines reach the API from GTFS route types 1551-1560. Before this mapping existed the + * mode could not be serialized, and a single carpool line made any query selecting + * {@code transportMode} fail. The mode enums are not exhaustive over {@link TransitMode}, so this + * test guards the one mode rather than the whole set. + */ + @Test + void assertCarpoolIsMappedInBothModeEnums() { + assertEquals(TransitMode.CARPOOL, mappedValue(TRANSPORT_MODE, "carpool")); + assertEquals(TransitMode.CARPOOL, mappedValue(LEG_MODE, "carpool")); + } + + private static Object mappedValue(GraphQLEnumType type, String apiName) { + var value = type.getValue(apiName); + assertNotNull(value, () -> "'%s' is not mapped in enum %s".formatted(apiName, type.getName())); + return value.getValue(); + } + private enum Foo implements DocumentedEnum { Hi(HI_DESCRIPTION), Bar(BAR_DESCRIPTION); diff --git a/application/src/test/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyTypeTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyTypeTest.java index a70797bcd32..563579d35de 100644 --- a/application/src/test/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyTypeTest.java +++ b/application/src/test/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyTypeTest.java @@ -21,10 +21,16 @@ import org.opentripplanner.api.model.transit.DefaultFeedIdMapper; import org.opentripplanner.apis.transmodel.TransmodelRequestContext; import org.opentripplanner.apis.transmodel.model.framework.TransmodelDirectives; +import org.opentripplanner.routing.api.request.RouteRequest; +import org.opentripplanner.routing.linking.VertexLinkerTestFactory; +import org.opentripplanner.standalone.api.TestServerContext; +import org.opentripplanner.street.graph.Graph; +import org.opentripplanner.transfer.regular.TransferRepository; +import org.opentripplanner.transfer.regular.TransferServiceTestFactory; import org.opentripplanner.transit.model.TransitTestEnvironment; import org.opentripplanner.transit.model.TransitTestEnvironmentBuilder; import org.opentripplanner.transit.model.TripInput; -import org.opentripplanner.transit.model.calendar.DefaultTripCalendars; +import org.opentripplanner.transit.model.calendar.TripCalendars; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.timetable.RealTimeTripTimesBuilder; import org.opentripplanner.transit.model.timetable.RealTimeTripUpdate; @@ -65,13 +71,13 @@ void realTimeJourneyState_isNull_whenTripTimesNotFound() { var unknownTrip = Trip.of(id("does-not-exist")).withRoute(envBuilder.route("Runknown")).build(); var tripOnServiceDate = tripOnServiceDate(unknownTrip); - assertNull(fetch(env.transitService(), tripOnServiceDate)); + assertNull(fetch(env, tripOnServiceDate)); } @Test void realTimeJourneyState_allFlagsFalse_forScheduledTrip() { var env = envBuilder.addTrip(TRIP_INPUT).build(); - var state = fetch(env.transitService(), tripOnServiceDate(env, TRIP_ID)); + var state = fetch(env, tripOnServiceDate(env, TRIP_ID)); assertFalse(flag(state, "extraJourney")); assertFalse(flag(state, "cancellation")); @@ -82,7 +88,7 @@ void realTimeJourneyState_allFlagsFalse_forScheduledTrip() { @Test void realTimeJourneyState_cancellationFlag() { - var state = fetchWithUpdate(builder -> builder.withCanceled()); + var state = fetchWithUpdate(RealTimeTripTimesBuilder::withCanceled); assertTrue(flag(state, "cancellation")); assertTrue(flag(state, "updated")); @@ -93,7 +99,7 @@ void realTimeJourneyState_cancellationFlag() { @Test void realTimeJourneyState_timesModifiedFlag() { - var state = fetchWithUpdate(builder -> builder.withRealTimeUpdated()); + var state = fetchWithUpdate(RealTimeTripTimesBuilder::withRealTimeUpdated); assertTrue(flag(state, "timesModified")); assertTrue(flag(state, "updated")); @@ -104,7 +110,7 @@ void realTimeJourneyState_timesModifiedFlag() { @Test void realTimeJourneyState_extraJourneyFlag() { - var state = fetchWithUpdate(builder -> builder.withAdded()); + var state = fetchWithUpdate(RealTimeTripTimesBuilder::withAdded); assertTrue(flag(state, "extraJourney")); assertTrue(flag(state, "updated")); @@ -113,7 +119,7 @@ void realTimeJourneyState_extraJourneyFlag() { @Test void realTimeJourneyState_journeyPatternModifiedFlag() { - var state = fetchWithUpdate(builder -> builder.withModifiedTripPattern()); + var state = fetchWithUpdate(RealTimeTripTimesBuilder::withModifiedTripPattern); assertTrue(flag(state, "journeyPatternModified")); assertTrue(flag(state, "updated")); @@ -135,8 +141,10 @@ private Map fetchWithUpdate(Consumer c customize.accept(builder); var tripTimes = builder.build(); var update = RealTimeTripUpdate.of(tripData.tripPattern(), tripTimes, SERVICE_DATE).build(); - var transitService = transitServiceWithUpdate(env, update); - return fetch(transitService, tripOnServiceDate(env, TRIP_ID)); + + env.applyUpdate(update); + + return fetch(env, tripOnServiceDate(env, TRIP_ID)); } /** Builds a {@link TransitService} that sees the given real-time update in its snapshot. */ @@ -147,7 +155,7 @@ private static TransitService transitServiceWithUpdate( var repo = env.transitRepository(); var snapshot = new DefaultTimetableRepository( repo.getRaptorTransitData(), - new DefaultTripCalendars() + TripCalendars.empty() ); snapshot.update(update); return new DefaultTransitService(repo, snapshot.commit()); @@ -172,10 +180,31 @@ private static boolean flag(Map state, String name) { @SuppressWarnings("unchecked") private static Map fetch( - TransitService transitService, + TransitTestEnvironment env, TripOnServiceDate tripOnServiceDate ) { - var context = new TransmodelRequestContext(null, null, transitService, null); + var transitService = env.transitService(); + var graph = new Graph(); + var vertexLinker = VertexLinkerTestFactory.of(graph); + var defaultRequest = RouteRequest.defaultValue(); + + TransferRepository transferRepository = TransferServiceTestFactory.defaultTransferRepository(); + + TransmodelRequestContext context = new TransmodelRequestContext( + TestServerContext.createRoutingService(graph, transitService, transferRepository), + transitService, + null, + null, + defaultRequest, + TestServerContext.createVehicleRentalService(), + TestServerContext.createVehicleParkingService(), + graph, + TransferServiceTestFactory.transferService(transferRepository), + TestServerContext.createStreetDetailsService(), + TestServerContext.createLinkingContextFactory(graph, vertexLinker, transitService), + TestServerContext.createStreetLimitationParametersService() + ); + var result = GRAPHQL.execute( ExecutionInput.newExecutionInput() .query( diff --git a/application/src/test/java/org/opentripplanner/apis/vectortiles/DebugVectorTilesResourceTest.java b/application/src/test/java/org/opentripplanner/apis/vectortiles/DebugVectorTilesResourceTest.java index 951270d73e2..408b9015291 100644 --- a/application/src/test/java/org/opentripplanner/apis/vectortiles/DebugVectorTilesResourceTest.java +++ b/application/src/test/java/org/opentripplanner/apis/vectortiles/DebugVectorTilesResourceTest.java @@ -5,9 +5,9 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner.apis.vectortiles.model.LayerType; -import org.opentripplanner.ext.fares.service.NoopFareServiceFactory; import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.standalone.api.TestServerContext; +import org.opentripplanner.standalone.config.DebugUiConfig; import org.opentripplanner.street.graph.Graph; import org.opentripplanner.test.support.HttpForTest; import org.opentripplanner.transfer.regular.TransferServiceTestFactory; @@ -29,20 +29,20 @@ public String mapper() { @Test void tileJson() { - var serverContext = TestServerContext.createServerContext( - new Graph(), + var graph = new Graph(); + var transferRepository = TransferServiceTestFactory.defaultTransferRepository(); + var transitService = TestServerContext.createTransitService( new TransitRepository(), - TransferServiceTestFactory.defaultTransferRepository(), - new NoopFareServiceFactory().makeFareService() + transferRepository ); var resource = new DebugVectorTilesResource( - serverContext.transitService(), - serverContext.graph(), - serverContext.debugUiConfig(), - serverContext.worldEnvelopeService(), - serverContext.vehicleRentalService(), - serverContext.streetDetailsService(), - serverContext.transferService() + transitService, + graph, + DebugUiConfig.DEFAULT, + TestServerContext.createWorldEnvelopeService(), + TestServerContext.createVehicleRentalService(), + TestServerContext.createStreetDetailsService(), + TransferServiceTestFactory.transferService(transferRepository) ); var req = HttpForTest.containerRequest(); var tileJson = resource.getTileJson(req.getUriInfo(), req, "l1,l2"); diff --git a/application/src/test/java/org/opentripplanner/datastore/OtpDataStoreTest.java b/application/src/test/java/org/opentripplanner/datastore/OtpDataStoreTest.java index d3ba6f257c1..48f7b5a56d8 100644 --- a/application/src/test/java/org/opentripplanner/datastore/OtpDataStoreTest.java +++ b/application/src/test/java/org/opentripplanner/datastore/OtpDataStoreTest.java @@ -159,12 +159,12 @@ public void testResolvingFileUris() throws IOException { graph: '%s', buildReportDir: '%s' }""".formatted( - uri + OSM_FILENAME, - uri + GTFS_FILENAME, - uri + EMPIRICAL_DELAY, - uri + GRAPH_FILENAME, - uri + REPORT_FILENAME - ) + uri + OSM_FILENAME, + uri + GTFS_FILENAME, + uri + EMPIRICAL_DELAY, + uri + GRAPH_FILENAME, + uri + REPORT_FILENAME + ) ); // Create build-config and an unknown file in the 'baseDir' @@ -269,19 +269,17 @@ private List listFilesByRelativeName(OtpDataStore store, File baseDir, F List files = new ArrayList<>(); for (FileType type : FileType.values()) { - store - .listExistingSourcesFor(type) - .forEach(s -> { - String p = s.path(); - - if (p.startsWith(baseDirPath)) { - // Add 1 to strip off path separator - p = "base:" + p.substring(baseDirPath.length() + 1); - } else if (p.startsWith(dataDirPath)) { - p = "data:" + p.substring(dataDirPath.length() + 1); - } - files.add(type.name() + " " + p); - }); + store.listExistingSourcesFor(type).forEach(s -> { + String p = s.path(); + + if (p.startsWith(baseDirPath)) { + // Add 1 to strip off path separator + p = "base:" + p.substring(baseDirPath.length() + 1); + } else if (p.startsWith(dataDirPath)) { + p = "data:" + p.substring(dataDirPath.length() + 1); + } + files.add(type.name() + " " + p); + }); } return files; } diff --git a/application/src/test/java/org/opentripplanner/framework/application/OTPFeatureTest.java b/application/src/test/java/org/opentripplanner/framework/application/OTPFeatureTest.java index 92e8e2e1575..dbdc6050cb1 100644 --- a/application/src/test/java/org/opentripplanner/framework/application/OTPFeatureTest.java +++ b/application/src/test/java/org/opentripplanner/framework/application/OTPFeatureTest.java @@ -51,13 +51,13 @@ public void allowOTPFeaturesToBeConfigurableFromJSON() { // Given the following config String json = """ - { - otpFeatures : { - GtfsGraphQlApi: false, - MinimumTransferTimeIsDefinitive : true - } + { + otpFeatures : { + GtfsGraphQlApi: false, + MinimumTransferTimeIsDefinitive : true } - """; + } + """; var configLoader = OtpConfigLoader.fromString(json); var config = configLoader.loadOtpConfig(); diff --git a/application/src/test/java/org/opentripplanner/framework/csv/parser/AbstractCsvParserTest.java b/application/src/test/java/org/opentripplanner/framework/csv/parser/AbstractCsvParserTest.java index 5c0df9f72a3..ca5b8609be0 100644 --- a/application/src/test/java/org/opentripplanner/framework/csv/parser/AbstractCsvParserTest.java +++ b/application/src/test/java/org/opentripplanner/framework/csv/parser/AbstractCsvParserTest.java @@ -38,10 +38,10 @@ class AbstractCsvParserTest { private static final String VALID_DATA = FILE_HEADER + """ - F:1, 1, 28.0, 1, 2025-10-31 - F:2, 2, 38.0, 0, 20250101 - F:3, 3, 48.0, 1, 2025-02-28 - """; + F:1, 1, 28.0, 1, 2025-10-31 + F:2, 2, 38.0, 0, 20250101 + F:3, 3, 48.0, 1, 2025-02-28 + """; @Test void headersDoesNotExistForEmptyFile() { diff --git a/application/src/test/java/org/opentripplanner/framework/transaction/moduletest/candyshop/customer/internal/CustomerRepositoryLifecycle.java b/application/src/test/java/org/opentripplanner/framework/transaction/moduletest/candyshop/customer/internal/CustomerRepositoryLifecycle.java index 63f5eae3170..aea61b893a2 100644 --- a/application/src/test/java/org/opentripplanner/framework/transaction/moduletest/candyshop/customer/internal/CustomerRepositoryLifecycle.java +++ b/application/src/test/java/org/opentripplanner/framework/transaction/moduletest/candyshop/customer/internal/CustomerRepositoryLifecycle.java @@ -11,7 +11,8 @@ * follow every task. */ public class CustomerRepositoryLifecycle - implements RepositoryLifecycle { + implements RepositoryLifecycle +{ @Override public CustomerRepository copyOnWrite(CustomerRepositorySnapshot snapshot) { diff --git a/application/src/test/java/org/opentripplanner/framework/transaction/moduletest/candyshop/event/CustomerEventHandler.java b/application/src/test/java/org/opentripplanner/framework/transaction/moduletest/candyshop/event/CustomerEventHandler.java index 6ce6ddd8ba3..d039d4d3080 100644 --- a/application/src/test/java/org/opentripplanner/framework/transaction/moduletest/candyshop/event/CustomerEventHandler.java +++ b/application/src/test/java/org/opentripplanner/framework/transaction/moduletest/candyshop/event/CustomerEventHandler.java @@ -5,7 +5,8 @@ import org.opentripplanner.framework.transaction.moduletest.candyshop.customer.model.Customer; public class CustomerEventHandler - implements EventHandler { + implements EventHandler +{ @Override public Class eventType() { diff --git a/application/src/test/java/org/opentripplanner/framework/transaction/moduletest/candyshop/order/internal/OrderRepositoryLifecycle.java b/application/src/test/java/org/opentripplanner/framework/transaction/moduletest/candyshop/order/internal/OrderRepositoryLifecycle.java index 6c61859b860..95e6cdc1f23 100644 --- a/application/src/test/java/org/opentripplanner/framework/transaction/moduletest/candyshop/order/internal/OrderRepositoryLifecycle.java +++ b/application/src/test/java/org/opentripplanner/framework/transaction/moduletest/candyshop/order/internal/OrderRepositoryLifecycle.java @@ -12,7 +12,8 @@ * only the freeze action triggers copying the internal data structure. */ public class OrderRepositoryLifecycle - implements RepositoryLifecycle { + implements RepositoryLifecycle +{ // The one live, mutable repository instance, reused for every transaction - not derived from // the published snapshot, since freeze() always returns a decoupled copy of it. diff --git a/application/src/test/java/org/opentripplanner/generate/doc/StopConsolidationDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/StopConsolidationDocTest.java index 15649847c22..abc06d30d2d 100644 --- a/application/src/test/java/org/opentripplanner/generate/doc/StopConsolidationDocTest.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/StopConsolidationDocTest.java @@ -42,10 +42,10 @@ public void updateDoc() { var joined = String.join("\n", lines); var csvExample = """ - ``` - %s - ``` - """.formatted(joined); + ``` + %s + ``` + """.formatted(joined); template = replaceSection(template, "config", updaterDoc(node)); template = replaceSection(template, "file", csvExample); diff --git a/application/src/test/java/org/opentripplanner/generate/doc/framework/ParameterDetailsList.java b/application/src/test/java/org/opentripplanner/generate/doc/framework/ParameterDetailsList.java index ea165d3dc16..be96676df40 100644 --- a/application/src/test/java/org/opentripplanner/generate/doc/framework/ParameterDetailsList.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/framework/ParameterDetailsList.java @@ -97,7 +97,10 @@ void addMetaInfo(NodeInfo info, String path) { doc.dotSeparator().label("Default value:").code(info.type().quote(info.defaultValue())); } - doc.lineBreak().label("Path:").path(path == null ? "/" : "/" + path.replace('.', '/')); + doc + .lineBreak() + .label("Path:") + .path(path == null ? "/" : "/" + path.replace('.', '/')); skipNodes .linkDetails(info) diff --git a/application/src/test/java/org/opentripplanner/generate/doc/framework/TemplateUtil.java b/application/src/test/java/org/opentripplanner/generate/doc/framework/TemplateUtil.java index d5e991d9fde..173ca2154f2 100644 --- a/application/src/test/java/org/opentripplanner/generate/doc/framework/TemplateUtil.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/framework/TemplateUtil.java @@ -38,12 +38,13 @@ public static String replaceSection(String doc, String token, String replacement throw new IllegalStateException("Doc did not contain token: " + replaceToken); } var replacementText = """ - - + + - %s - - """.trim() + %s + + """ + .trim() .formatted(token, replacement, token); return doc.replace(replaceToken, replacementText); diff --git a/application/src/test/java/org/opentripplanner/generate/doc/framework/TemplateUtilTest.java b/application/src/test/java/org/opentripplanner/generate/doc/framework/TemplateUtilTest.java index 6ede70f5c03..854143486ad 100644 --- a/application/src/test/java/org/opentripplanner/generate/doc/framework/TemplateUtilTest.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/framework/TemplateUtilTest.java @@ -14,9 +14,9 @@ public class TemplateUtilTest { @Test public void replaceSectionTest() { var body = """ - Expected line 1. - Expected line 2. - """; + Expected line 1. + Expected line 2. + """; var doc = ""; assertEquals( diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/VehicleParkingLinkingTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/VehicleParkingLinkingTest.java index cb6c58a6f28..6d9e8621ee8 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/VehicleParkingLinkingTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/VehicleParkingLinkingTest.java @@ -1,5 +1,6 @@ package org.opentripplanner.graph_builder.module; +import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.core.model.id.FeedScopedIdForTestFactory.id; @@ -77,12 +78,13 @@ public void entranceWithoutVertexLinkingTest() { TestStreetLinkerModule.link(graph, transitRepository); - var streetLinks = graph.getEdgesOfType(StreetVehicleParkingLink.class); - assertEquals(2, streetLinks.size()); + assertThat(graph.findEdges(StreetVehicleParkingLink.class)).hasSize(2); - streetLinks.forEach(e -> - assertTrue(e.getFromVertex().equals(parkingVertex) ^ e.getToVertex().equals(parkingVertex)) - ); + graph + .findEdges(StreetVehicleParkingLink.class) + .forEach(e -> + assertTrue(e.getFromVertex().equals(parkingVertex) ^ e.getToVertex().equals(parkingVertex)) + ); } @Test @@ -110,12 +112,13 @@ public void carParkingEntranceToAllTraversableStreetLinkingTest() { TestStreetLinkerModule.link(graph, transitRepository); - var streetLinks = graph.getEdgesOfType(StreetVehicleParkingLink.class); - assertEquals(4, streetLinks.size()); + assertThat(graph.findEdges(StreetVehicleParkingLink.class)).hasSize(4); - streetLinks.forEach(e -> - assertTrue(e.getFromVertex().equals(parkingVertex) ^ e.getToVertex().equals(parkingVertex)) - ); + graph + .findEdges(StreetVehicleParkingLink.class) + .forEach(e -> + assertTrue(e.getFromVertex().equals(parkingVertex) ^ e.getToVertex().equals(parkingVertex)) + ); } @Test @@ -148,8 +151,8 @@ public void removeEntranceWithNonExistingVertexTest() { assertEquals(1, graph.getVerticesOfType(VehicleParkingEntranceVertex.class).size()); - assertEquals(1, graph.getEdgesOfType(VehicleParkingEdge.class).size()); - assertEquals(2, graph.getEdgesOfType(StreetVehicleParkingLink.class).size()); + assertThat(graph.findEdges(VehicleParkingEdge.class)).hasSize(1); + assertThat(graph.findEdges(StreetVehicleParkingLink.class)).hasSize(2); } @Test @@ -175,10 +178,10 @@ public void removeVehicleParkingWithOneEntranceAndNonExistingVertexTest() { assertEquals(0, graph.getVerticesOfType(VehicleParkingEntranceVertex.class).size()); - assertEquals(0, graph.getEdgesOfType(VehicleParkingEdge.class).size()); - assertEquals(0, graph.getEdgesOfType(StreetVehicleParkingLink.class).size()); + assertThat(graph.findEdges(VehicleParkingEdge.class)).isEmpty(); + assertThat(graph.findEdges(StreetVehicleParkingLink.class)).isEmpty(); - assertEquals(0, graph.getEdgesOfType(StreetVehicleParkingLink.class).size()); + assertThat(graph.findEdges(StreetVehicleParkingLink.class)).isEmpty(); assertEquals(0, vehicleParkingService.listVehicleParkings().size()); } } diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/AdaptivePruningTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/AdaptivePruningTest.java index 7ecce7e9f38..1935b2a34b9 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/AdaptivePruningTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/AdaptivePruningTest.java @@ -7,7 +7,7 @@ import java.util.stream.Collectors; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.opentripplanner.street.graph.Graph; +import org.opentripplanner.street.graph.summary.GraphSummarizer; import org.opentripplanner.test.support.ResourceLoader; /** @@ -18,7 +18,7 @@ */ class AdaptivePruningTest { - private static Graph graph; + private static GraphSummarizer graph; @BeforeAll static void setup() { @@ -37,7 +37,7 @@ static void setup() { void distantIslandIsRetained() { assertTrue( graph - .getStreetEdges() + .listStreetEdges() .stream() .map(streetEdge -> streetEdge.getName().toString()) .collect(Collectors.toSet()) @@ -49,7 +49,7 @@ void distantIslandIsRetained() { void nearIslandIsRemoved() { assertFalse( graph - .getStreetEdges() + .listStreetEdges() .stream() .map(streetEdge -> streetEdge.getName().toString()) .collect(Collectors.toSet()) @@ -61,7 +61,7 @@ void nearIslandIsRemoved() { void mainGraphIsNotRemoved() { assertTrue( graph - .getStreetEdges() + .listStreetEdges() .stream() .map(streetEdge -> streetEdge.getName().toString()) .collect(Collectors.toSet()) diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/EscalatorPruningTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/EscalatorPruningTest.java index d754bdd86d0..3186461c409 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/EscalatorPruningTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/EscalatorPruningTest.java @@ -17,7 +17,7 @@ void streetEdgesBetweenEscalatorEdgesRetained() { ); assertTrue( graph - .getStreetEdges() + .listStreetEdges() .stream() .map(streetEdge -> streetEdge.getName().toString()) .collect(Collectors.toSet()) diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/PruneNoThruIslandsTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/PruneNoThruIslandsTest.java index 716bd181ffb..02ac4c652bc 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/PruneNoThruIslandsTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/PruneNoThruIslandsTest.java @@ -8,13 +8,13 @@ import java.util.stream.Collectors; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.opentripplanner.street.graph.Graph; +import org.opentripplanner.street.graph.summary.GraphSummarizer; import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.test.support.ResourceLoader; class PruneNoThruIslandsTest { - private static Graph graph; + private static GraphSummarizer graph; @BeforeAll static void setup() { @@ -30,7 +30,7 @@ static void setup() { void bicycleIslandsBecomeNoThru() { assertTrue( graph - .getStreetEdges() + .listStreetEdges() .stream() .filter(StreetEdge::isBicycleNoThruTraffic) .map(streetEdge -> streetEdge.getName().toString()) @@ -43,7 +43,7 @@ void bicycleIslandsBecomeNoThru() { void carIslandsBecomeNoThru() { assertTrue( graph - .getStreetEdges() + .listStreetEdges() .stream() .filter(StreetEdge::isMotorVehicleNoThruTraffic) .map(streetEdge -> streetEdge.getName().toString()) @@ -56,7 +56,7 @@ void carIslandsBecomeNoThru() { void pruneFloatingBikeAndWalkIsland() { assertFalse( graph - .getStreetEdges() + .listStreetEdges() .stream() .map(streetEdge -> streetEdge.getName().toString()) .collect(Collectors.toSet()) diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/BarrierEdgeBuilderTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/BarrierEdgeBuilderTest.java index adcd648777e..6b94e31e7d6 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/BarrierEdgeBuilderTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/BarrierEdgeBuilderTest.java @@ -14,8 +14,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.graph_builder.services.osm.DefaultNamer; -import org.opentripplanner.graph_builder.services.osm.EdgeNamer; +import org.opentripplanner.graph_builder.module.osm.internal.naming.DefaultNamer; import org.opentripplanner.osm.model.OsmNode; import org.opentripplanner.osm.model.OsmWay; import org.opentripplanner.street.geometry.GeometryUtils; diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmModuleTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmModuleTest.java index 14362d846c7..1d938828b3c 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmModuleTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmModuleTest.java @@ -127,7 +127,7 @@ public void testBuildGraphDetailed() { assertFalse(iv8.hasDrivingTrafficLight()); Set edgeEndpoints = new HashSet<>(); - for (StreetEdge se : gg.getStreetEdges()) { + for (StreetEdge se : gg.findEdges(StreetEdge.class)) { var endpoints = new VertexPair(se.getFromVertex(), se.getToVertex()); // Check that we don't get any duplicate edges on this small graph. if (edgeEndpoints.contains(endpoints)) { diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/PlatformEntranceFinderTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/PlatformEntranceFinderTest.java similarity index 98% rename from application/src/test/java/org/opentripplanner/graph_builder/module/osm/PlatformEntranceFinderTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/PlatformEntranceFinderTest.java index 9fadd5ec7a8..2a493187a5c 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/PlatformEntranceFinderTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/PlatformEntranceFinderTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.internal.walkablearea; import static com.google.common.truth.Truth.assertThat; import static org.opentripplanner.street.model.StreetModelForTest.intersectionVertex; diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilderTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/WalkableAreaBuilderTest.java similarity index 90% rename from application/src/test/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilderTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/WalkableAreaBuilderTest.java index 32216ab67d7..54964f990ae 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilderTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/WalkableAreaBuilderTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.internal.walkablearea; import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.util.stream.Collectors.toMap; @@ -19,11 +19,17 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInfo; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; -import org.opentripplanner.graph_builder.services.osm.DefaultNamer; +import org.opentripplanner.graph_builder.module.osm.SafetyValueApplier; +import org.opentripplanner.graph_builder.module.osm.internal.naming.DefaultNamer; +import org.opentripplanner.graph_builder.module.osm.model.OsmArea; +import org.opentripplanner.graph_builder.module.osm.model.OsmAreaGroup; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; +import org.opentripplanner.graph_builder.module.osm.storage.VertexGenerator; import org.opentripplanner.osm.DefaultOsmProvider; import org.opentripplanner.osm.model.OsmLevel; import org.opentripplanner.service.osminfo.internal.DefaultOsmInfoGraphBuildRepository; import org.opentripplanner.street.graph.Graph; +import org.opentripplanner.street.graph.summary.GraphSummarizer; import org.opentripplanner.street.model.edge.AreaEdge; import org.opentripplanner.street.model.vertex.VertexLabel; import org.opentripplanner.street.model.vertex.VertexLabel.VertexWithEntityLabel; @@ -33,7 +39,7 @@ public class WalkableAreaBuilderTest { private DefaultOsmInfoGraphBuildRepository osmInfoRepository; - public Graph buildGraph(final TestInfo testInfo) { + public GraphSummarizer buildGraph(final TestInfo testInfo) { var graph = new Graph(); final Method testMethod = testInfo.getTestMethod().get(); final String osmFile = testMethod.getAnnotation(OsmFile.class).value(); @@ -77,7 +83,7 @@ public Graph buildGraph(final TestInfo testInfo) { : walkableAreaBuilder::buildWithoutVisibility; areaGroups.forEach(build); - return graph; + return new GraphSummarizer(graph); } // -- Tests -- @@ -89,7 +95,7 @@ public Graph buildGraph(final TestInfo testInfo) { void testCalculateVerticesArea(TestInfo testInfo) { var graph = buildGraph(testInfo); var areas = graph - .getEdgesOfType(AreaEdge.class) + .listAreaEdges() .stream() .filter(a -> a.getToVertex().getLabel().equals(VertexLabel.osm(1025307935))) .map(AreaEdge::getArea) @@ -106,7 +112,7 @@ void testCalculateVerticesArea(TestInfo testInfo) { void testSetupCalculateVerticesAreaWithoutVisibility(TestInfo testInfo) { var graph = buildGraph(testInfo); var areas = graph - .getEdgesOfType(AreaEdge.class) + .listAreaEdges() .stream() .filter(a -> a.getToVertex().getLabel().equals(VertexLabel.osm(1025307935))) .map(AreaEdge::getArea) @@ -126,7 +132,7 @@ void testEntranceStopAreaLinking(TestInfo testInfo) { var graph = buildGraph(testInfo); // first platform contains isolated node tagged as highway=bus_stop. Those are linked if level matches. var busStopConnection = graph - .getEdgesOfType(AreaEdge.class) + .listAreaEdges() .stream() .filter(a -> a.getToVertex().getLabel().equals(VertexLabel.osm(143853))) .map(AreaEdge::getArea) @@ -136,7 +142,7 @@ void testEntranceStopAreaLinking(TestInfo testInfo) { // first platform has level 0, entrance below it has level -1 -> no links var entranceAtWrongLevel = graph - .getEdgesOfType(AreaEdge.class) + .listAreaEdges() .stream() .filter(a -> a.getToVertex().getLabel().equals(VertexLabel.osm(143850))) .map(AreaEdge::getArea) @@ -146,7 +152,7 @@ void testEntranceStopAreaLinking(TestInfo testInfo) { // second platform and its entrance both default to level zero, entrance gets connected var entranceAtSameLevel = graph - .getEdgesOfType(AreaEdge.class) + .listAreaEdges() .stream() .filter(a -> elevatorVertexConnectedToAreaEdgeHasNodeId(a, 143832)) .map(AreaEdge::getArea) @@ -157,7 +163,7 @@ void testEntranceStopAreaLinking(TestInfo testInfo) { // second platform also contains a stop position which is not considered as an entrance // therefore it should not get linked var stopPositionConnection = graph - .getEdgesOfType(AreaEdge.class) + .listAreaEdges() .stream() .filter(a -> a.getToVertex().getLabel().equals(VertexLabel.osm(143863))) .map(AreaEdge::getArea) @@ -169,7 +175,7 @@ void testEntranceStopAreaLinking(TestInfo testInfo) { // and there are not too many connections (to remote platforms) // third platform also tests the 'layer' tag var connectionEdges = graph - .getEdgesOfType(AreaEdge.class) + .listAreaEdges() .stream() .filter(a -> elevatorVertexConnectedToAreaEdgeHasNodeId(a, 143845)) .toList(); @@ -180,7 +186,7 @@ void testEntranceStopAreaLinking(TestInfo testInfo) { // test that semicolon separated list of elevator levals works in level matching // e.g. 'level'='0;1' var elevatorConnection = graph - .getEdgesOfType(AreaEdge.class) + .listAreaEdges() .stream() .filter(a -> elevatorVertexConnectedToAreaEdgeHasNodeId(a, 143861)) .map(AreaEdge::getArea) @@ -191,7 +197,7 @@ void testEntranceStopAreaLinking(TestInfo testInfo) { // first platform area has ref tag. Check that it is available in // DefaultOsmInfoGraphBuildRepository var areaGroups = graph - .getEdgesOfType(AreaEdge.class) + .listAreaEdges() .stream() .filter(a -> a.getToVertex().getLabel().equals(VertexLabel.osm(143846))) .map(AreaEdge::getArea) @@ -213,7 +219,7 @@ void testEntranceStopAreaLinking(TestInfo testInfo) { void testSeveralIntersections(TestInfo testInfo) { var graph = buildGraph(testInfo); var areas = graph - .getEdgesOfType(AreaEdge.class) + .listAreaEdges() .stream() .filter(a -> a.getToVertex().getLabel().equals(VertexLabel.osm(2522105666L))) .map(AreaEdge::getArea) diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/DisjointSetTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/model/DisjointSetTest.java similarity index 96% rename from application/src/test/java/org/opentripplanner/graph_builder/module/osm/DisjointSetTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/model/DisjointSetTest.java index bcc143e5213..5ce0213d92f 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/DisjointSetTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/model/DisjointSetTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.model; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmAreaGroupTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/model/OsmAreaGroupTest.java similarity index 99% rename from application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmAreaGroupTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/model/OsmAreaGroupTest.java index 846ada993a8..a62318ddc1e 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmAreaGroupTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/model/OsmAreaGroupTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.model; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/RingTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/model/RingTest.java similarity index 96% rename from application/src/test/java/org/opentripplanner/graph_builder/module/osm/RingTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/model/RingTest.java index 2ea406524b3..ec515f8a965 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/RingTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/model/RingTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.model; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/BarrierTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/BarrierTest.java index 2d8750a0ad3..cda25542930 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/BarrierTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/BarrierTest.java @@ -14,8 +14,8 @@ import org.opentripplanner.graph_builder.issue.service.DefaultDataImportIssueStore; import org.opentripplanner.graph_builder.issues.BarrierIntersectingHighway; import org.opentripplanner.graph_builder.issues.DifferentLevelsSharingBarrier; -import org.opentripplanner.graph_builder.module.osm.OsmDatabase; import org.opentripplanner.graph_builder.module.osm.OsmModuleTestFactory; +import org.opentripplanner.graph_builder.module.osm.storage.OsmDatabase; import org.opentripplanner.osm.TestOsmProvider; import org.opentripplanner.osm.model.OsmNode; import org.opentripplanner.osm.model.OsmWay; @@ -39,7 +39,12 @@ void testLinearCrossingNonIntersection() { List.of(way, barrier), Set.of(1, 2, 3, 4, 98, 99) .stream() - .map(id -> OsmNode.of().withId(id).withLatLon((double) id / 1000, 0).build()) + .map(id -> + OsmNode.of() + .withId(id) + .withLatLon((double) id / 1000, 0) + .build() + ) .toList() ); diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/BoardingLocationTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/BoardingLocationTest.java index 1ba588eb5e8..abf1b18de45 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/BoardingLocationTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/BoardingLocationTest.java @@ -4,7 +4,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.util.List; import java.util.Set; import org.junit.jupiter.api.Test; import org.opentripplanner.graph_builder.module.osm.OsmModuleTestFactory; @@ -13,6 +12,7 @@ import org.opentripplanner.osm.model.OsmWay; import org.opentripplanner.service.osminfo.internal.DefaultOsmInfoGraphBuildRepository; import org.opentripplanner.street.graph.Graph; +import org.opentripplanner.utils.collection.ListUtils; class BoardingLocationTest { @@ -40,7 +40,7 @@ void oneWayPlatform() { .build(); osmModule.buildGraph(); - var edges = List.copyOf(graph.getEdges()); + var edges = ListUtils.ofIterable(graph.listEdges()); assertThat(edges).hasSize(1); var platform = osmInfoRepository.findPlatform(edges.getFirst()); @@ -64,7 +64,7 @@ void skipPlatformsWithoutReferences() { .build(); osmModule.buildGraph(); - var edges = List.copyOf(graph.getEdges()); + var edges = ListUtils.ofIterable(graph.listEdges()); assertThat(edges).hasSize(2); var platform = osmInfoRepository.findPlatform(edges.getFirst()); @@ -87,7 +87,7 @@ void testHighwayPlatform() { .build(); osmModule.buildGraph(); - var edges = List.copyOf(graph.getEdges()); + var edges = ListUtils.ofIterable(graph.listEdges()); assertThat(edges).hasSize(2); var platform = osmInfoRepository.findPlatform(edges.getFirst()); diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/EdgeLevelInfoTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/EdgeLevelInfoTest.java index 833e9bb64cf..fdb5c87abd3 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/EdgeLevelInfoTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/EdgeLevelInfoTest.java @@ -6,6 +6,7 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; +import java.util.stream.StreamSupport; import org.junit.jupiter.api.Test; import org.opentripplanner.graph_builder.module.osm.OsmModuleTestFactory; import org.opentripplanner.osm.TestOsmProvider; @@ -253,9 +254,7 @@ private Set getAllInclinedEdgeLevelInfoObjects( Graph graph, StreetDetailsRepository streetDetailsRepository ) { - return graph - .getEdges() - .stream() + return StreamSupport.stream(graph.listEdges().spliterator(), false) .flatMap(edge -> streetDetailsRepository .findInclinedEdgeLevelInfo(edge) @@ -269,9 +268,7 @@ private Set getAllHorizontalEdgeLevelInfoObjects( Graph graph, StreetDetailsRepository streetDetailsRepository ) { - return graph - .getEdges() - .stream() + return StreamSupport.stream(graph.listEdges().spliterator(), false) .flatMap(edge -> streetDetailsRepository .findHorizontalEdgeLevelInfo(edge) diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/DurationTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/DurationTest.java new file mode 100644 index 00000000000..86496447a39 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/DurationTest.java @@ -0,0 +1,58 @@ +package org.opentripplanner.graph_builder.module.osm.moduletests.elevator; + +import static com.google.common.truth.Truth.assertThat; +import static org.opentripplanner.osm.model.NodeBuilder.node; + +import java.time.Duration; +import org.junit.jupiter.api.Test; +import org.opentripplanner.graph_builder.module.osm.OsmModuleTestFactory; +import org.opentripplanner.osm.TestOsmProvider; +import org.opentripplanner.osm.model.NodeBuilder; +import org.opentripplanner.osm.model.OsmWay; +import org.opentripplanner.street.geometry.WgsCoordinate; +import org.opentripplanner.street.graph.Graph; +import org.opentripplanner.street.model.edge.ElevatorHopEdge; +import org.opentripplanner.utils.collection.ListUtils; + +class DurationTest { + + @Test + void testDuration() { + var way = OsmWay.of().withTag("duration", "00:01:02").withTag("highway", "elevator").build(); + var provider = TestOsmProvider.of().addWay(way).build(); + var graph = new Graph(); + var osmModule = OsmModuleTestFactory.of(provider).withGraph(graph).builder().build(); + + osmModule.buildGraph(); + + var edges = ListUtils.ofIterable(graph.findEdges(ElevatorHopEdge.class)); + assertThat(edges).hasSize(2); + for (var edge : edges) { + assertThat(edge.getTravelTime()).hasValue(Duration.ofSeconds(62)); + } + } + + @Test + void testMultilevelNodeDuration() { + var node0 = node(0, new WgsCoordinate(0, 0)); + var node1 = node(1, new WgsCoordinate(2, 0)); + var elevatorNode = NodeBuilder.of(2, new WgsCoordinate(1, 0)) + .withTag("duration", "00:01:02") + .withTag("highway", "elevator") + .withTag("level", "1;2") + .build(); + var provider = TestOsmProvider.of() + .addWayFromNodes(way -> way.withTag("level", "1"), node0, elevatorNode) + .addWayFromNodes(way -> way.withTag("level", "2"), node1, elevatorNode) + .build(); + var graph = new Graph(); + + OsmModuleTestFactory.of(provider).withGraph(graph).builder().build().buildGraph(); + + var edges = ListUtils.ofIterable(graph.findEdges(ElevatorHopEdge.class)); + assertThat(edges).hasSize(2); + for (var edge : edges) { + assertThat(edge.getTravelTime()).hasValue(Duration.ofSeconds(62)); + } + } +} diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/ElevatorIdTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/ElevatorIdTest.java new file mode 100644 index 00000000000..cb303f58d52 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/ElevatorIdTest.java @@ -0,0 +1,105 @@ +package org.opentripplanner.graph_builder.module.osm.moduletests.elevator; + +import static com.google.common.truth.Truth.assertThat; +import static org.opentripplanner.osm.model.NodeBuilder.node; + +import com.google.common.collect.ImmutableList; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.opentripplanner.graph_builder.module.osm.OsmModuleTestFactory; +import org.opentripplanner.osm.TestOsmProvider; +import org.opentripplanner.osm.model.CompoundRefTagGroup; +import org.opentripplanner.osm.model.NodeBuilder; +import org.opentripplanner.osm.model.OsmWay; +import org.opentripplanner.street.geometry.WgsCoordinate; +import org.opentripplanner.street.graph.Graph; +import org.opentripplanner.street.model.edge.ElevatorHopEdge; + +public class ElevatorIdTest { + + @Test + void testElevatorRefTagsOnNode() { + var node0 = node(0, new WgsCoordinate(0, 0)); + var node1 = node(1, new WgsCoordinate(2, 0)); + var elevatorNode = NodeBuilder.of(2, new WgsCoordinate(1, 0)) + .withTag("highway", "elevator") + .withTag("ref", "12345") + .build(); + var provider = TestOsmProvider.of() + .addWayFromNodes(way -> way.withTag("level", "1"), node0, elevatorNode) + .addWayFromNodes(way -> way.withTag("level", "2"), node1, elevatorNode) + .build(); + var graph = new Graph(); + + OsmModuleTestFactory.of(provider) + .withGraph(graph) + .builder() + .withElevatorRefTags(List.of(CompoundRefTagGroup.of("ref"))) + .build() + .buildGraph(); + + var edges = ImmutableList.copyOf(graph.findEdges(ElevatorHopEdge.class)); + assertThat(edges).hasSize(2); + for (var edge : edges) { + assertThat(edge.id()).hasValue("12345"); + } + } + + @Test + void testElevatorRefTagsOnWay() { + var n1 = node(1, new WgsCoordinate(0, 1)); + var n2 = node(2, new WgsCoordinate(0, 2)); + + var elevatorWay = OsmWay.of() + .withId(1) + .withTag("highway", "elevator") + .withTag("ref", "12345") + .addNodeRef(1, 2) + .build(); + + var provider = new TestOsmProvider(List.of(), List.of(elevatorWay), List.of(n1, n2)); + var graph = new Graph(); + + OsmModuleTestFactory.of(provider) + .withGraph(graph) + .builder() + .withElevatorRefTags(List.of(CompoundRefTagGroup.of("ref"))) + .build() + .buildGraph(); + + var edges = ImmutableList.copyOf(graph.findEdges(ElevatorHopEdge.class)); + assertThat(edges).hasSize(2); + for (var edge : edges) { + assertThat(edge.id()).hasValue("12345"); + } + } + + @Test + void testElevatorRefTagsEmptyWhenNoGroupResolves() { + var n1 = node(1, new WgsCoordinate(0, 1)); + var n2 = node(2, new WgsCoordinate(0, 2)); + + var elevatorWay = OsmWay.of() + .withId(1) + .withTag("highway", "elevator") + .withTag("ref", "12345") + .addNodeRef(1, 2) + .build(); + + var provider = new TestOsmProvider(List.of(), List.of(elevatorWay), List.of(n1, n2)); + var graph = new Graph(); + + OsmModuleTestFactory.of(provider) + .withGraph(graph) + .builder() + .withElevatorRefTags(List.of(CompoundRefTagGroup.of("manufacturer", "ref"))) + .build() + .buildGraph(); + + var edges = ImmutableList.copyOf(graph.findEdges(ElevatorHopEdge.class)); + assertThat(edges).hasSize(2); + for (var edge : edges) { + assertThat(edge.id()).isEmpty(); + } + } +} diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/ElevatorWayIntersectionNodeTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/ElevatorWayIntersectionNodeTest.java deleted file mode 100644 index c9d2d64accc..00000000000 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/ElevatorWayIntersectionNodeTest.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.opentripplanner.graph_builder.module.osm.moduletests.elevator; - -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; -import static org.opentripplanner.osm.model.NodeBuilder.node; - -import org.junit.jupiter.api.Test; -import org.opentripplanner.graph_builder.issue.api.DataImportIssue; -import org.opentripplanner.graph_builder.issue.service.DefaultDataImportIssueStore; -import org.opentripplanner.graph_builder.issues.FewerThanTwoIntersectionNodesInElevatorWay; -import org.opentripplanner.graph_builder.module.osm.OsmModuleTestFactory; -import org.opentripplanner.osm.TestOsmProvider; -import org.opentripplanner.street.geometry.WgsCoordinate; -import org.opentripplanner.street.graph.Graph; -import org.opentripplanner.street.graph.summary.GraphSummarizer; - -/** - * Regression test for a NullPointerException reported after #7905 ("Speed up OSM way - * processing"): an elevator way endpoint can be recorded as a candidate intersection node - * (because it is referenced by a second way) without ever getting a real graph vertex built for - * it. - *

- * In this test, node {@code b} sits at the same coordinate as the elevator way's other endpoint - * {@code a} - a mapping error rather than a legitimate way of tagging an elevator, but one that - * does occur in real OSM data - and carries no node-level "level" tag itself, so the - * duplicate-node handling in OsmModule's street-graph-building loop drops it while processing the - * elevator way: it never becomes the "from" or "to" node of a street edge there. Node {@code b} - * is also referenced by a second way that is relevant for routing (it's a bicycle parking way) - * but not "routable" in the street-graph sense, so OsmModule's street-graph-building loop skips - * that way entirely too. As a result no vertex is ever created for {@code b}, even though it was - * recorded as a candidate intersection node while scanning for nodes shared between ways - - * exactly the combination that made {@code ElevatorProcessor} crash: it found {@code b} in its - * list of candidate intersection nodes for the elevator way, then failed to look up a vertex that - * was never built. - *

- * The vertex-generator's intersection-node check must distinguish "candidate, not yet built" from - * "has a real vertex" so that elevator-way processing degrades gracefully (reporting a - * {@link FewerThanTwoIntersectionNodesInElevatorWay} issue) instead of crashing with a - * NullPointerException when it looks up the vertex. - */ -class ElevatorWayIntersectionNodeTest { - - @Test - void elevatorWayEndpointSharedWithNonRoutableWay() { - var a = node(1, new WgsCoordinate(1, 1)); - // `b` has the same coordinate as `a` and no level tag of its own - var b = node(2, new WgsCoordinate(1, 1)); - var c = node(3, new WgsCoordinate(2, 2)); - var d = node(4, new WgsCoordinate(3, 3)); - - var provider = TestOsmProvider.of() - .addWayFromNodes(way -> way.withTag("highway", "elevator").withTag("level", "0;-2"), a, b) - .addWayFromNodes(way -> way.withTag("highway", "footway"), a, c) - .addWayFromNodes( - way -> way.withTag("highway", "construction").withTag("amenity", "bicycle_parking"), - b, - d - ) - .build(); - var graph = new Graph(); - var issueStore = new DefaultDataImportIssueStore(); - - OsmModuleTestFactory.of(provider) - .withGraph(graph) - .builder() - .withIssueStore(issueStore) - .build() - .buildGraph(); - - var summarizer = new GraphSummarizer(graph); - - assertWithMessage("Expected no elevator hop edges. Check graph at %s", summarizer.geoJsonUrl()) - .that(summarizer.summarizeEdges()) - .containsExactly("(1,1) → (2,2) PEDESTRIAN ♿✅", "(2,2) → (1,1) PEDESTRIAN ♿✅"); - - var issues = issueStore.listIssues().stream().map(DataImportIssue::getType); - assertThat(issues).containsExactly("FewerThanTwoIntersectionNodesInElevatorWay"); - } -} diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/MalformedElevatorWayTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/MalformedElevatorWayTest.java new file mode 100644 index 00000000000..c7cbc3ca458 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/MalformedElevatorWayTest.java @@ -0,0 +1,117 @@ +package org.opentripplanner.graph_builder.module.osm.moduletests.elevator; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.osm.model.NodeBuilder.node; + +import org.junit.jupiter.api.Test; +import org.opentripplanner.graph_builder.issue.api.DataImportIssue; +import org.opentripplanner.graph_builder.issue.service.DefaultDataImportIssueStore; +import org.opentripplanner.graph_builder.issues.FewerThanTwoIntersectionNodesInElevatorWay; +import org.opentripplanner.graph_builder.module.osm.OsmModuleTestFactory; +import org.opentripplanner.osm.TestOsmProvider; +import org.opentripplanner.osm.model.NodeBuilder; +import org.opentripplanner.street.geometry.WgsCoordinate; +import org.opentripplanner.street.graph.Graph; +import org.opentripplanner.street.graph.summary.GraphSummarizer; +import org.opentripplanner.street.model.edge.ElevatorHopEdge; + +class MalformedElevatorWayTest { + + /** + * If the connected nodes of an elevator way have been modeled as elevators, they do not appear + * as intersection nodes. OTP should create an issue, but it should not cause errors. + */ + @Test + void elevatorWayWithFewerThanTwoIntersectionNodes() { + var n1 = NodeBuilder.of(1, new WgsCoordinate(1, 1)).withTag("highway", "elevator").build(); + var n2 = NodeBuilder.of(2, new WgsCoordinate(2, 2)).withTag("highway", "elevator").build(); + + var provider = TestOsmProvider.of() + .addWayFromNodes(way -> way.withTag("highway", "elevator"), n1, n2) + .build(); + var graph = new Graph(); + var issueStore = new DefaultDataImportIssueStore(); + + OsmModuleTestFactory.of(provider) + .withGraph(graph) + .builder() + .withIssueStore(issueStore) + .build() + .buildGraph(); + + var elevatorHopEdges = graph.findEdges(ElevatorHopEdge.class); + assertThat(elevatorHopEdges).hasSize(0); + + var issues = issueStore + .listIssues() + .stream() + .filter(issue -> issue instanceof FewerThanTwoIntersectionNodesInElevatorWay) + .map(FewerThanTwoIntersectionNodesInElevatorWay.class::cast) + .toList(); + assertEquals(1, issues.size()); + assertEquals(0, issues.getFirst().intersectionNodes()); + } + + /** + * Regression test for a NullPointerException reported after #7905 ("Speed up OSM way + * processing"): an elevator way endpoint can be recorded as a candidate intersection node + * (because it is referenced by a second way) without ever getting a real graph vertex built for + * it. + *

+ * In this test, node {@code b} sits at the same coordinate as the elevator way's other endpoint + * {@code a} - a mapping error rather than a legitimate way of tagging an elevator, but one that + * does occur in real OSM data - and carries no node-level "level" tag itself, so the + * duplicate-node handling in OsmModule's street-graph-building loop drops it while processing the + * elevator way: it never becomes the "from" or "to" node of a street edge there. Node {@code b} + * is also referenced by a second way that is relevant for routing (it's a bicycle parking way) + * but not "routable" in the street-graph sense, so OsmModule's street-graph-building loop skips + * that way entirely too. As a result no vertex is ever created for {@code b}, even though it was + * recorded as a candidate intersection node while scanning for nodes shared between ways - + * exactly the combination that made {@code ElevatorProcessor} crash: it found {@code b} in its + * list of candidate intersection nodes for the elevator way, then failed to look up a vertex that + * was never built. + *

+ * The vertex-generator's intersection-node check must distinguish "candidate, not yet built" from + * "has a real vertex" so that elevator-way processing degrades gracefully (reporting a + * {@link FewerThanTwoIntersectionNodesInElevatorWay} issue) instead of crashing with a + * NullPointerException when it looks up the vertex. + */ + @Test + void elevatorWayEndpointSharedWithNonRoutableWay() { + var a = node(1, new WgsCoordinate(1, 1)); + // `b` has the same coordinate as `a` and no level tag of its own + var b = node(2, new WgsCoordinate(1, 1)); + var c = node(3, new WgsCoordinate(2, 2)); + var d = node(4, new WgsCoordinate(3, 3)); + + var provider = TestOsmProvider.of() + .addWayFromNodes(way -> way.withTag("highway", "elevator").withTag("level", "0;-2"), a, b) + .addWayFromNodes(way -> way.withTag("highway", "footway"), a, c) + .addWayFromNodes( + way -> way.withTag("highway", "construction").withTag("amenity", "bicycle_parking"), + b, + d + ) + .build(); + var graph = new Graph(); + var issueStore = new DefaultDataImportIssueStore(); + + OsmModuleTestFactory.of(provider) + .withGraph(graph) + .builder() + .withIssueStore(issueStore) + .build() + .buildGraph(); + + var summarizer = new GraphSummarizer(graph); + + assertWithMessage("Expected no elevator hop edges. Check graph at %s", summarizer.geoJsonUrl()) + .that(summarizer.summarizeEdges()) + .containsExactly("(1,1) → (2,2) PEDESTRIAN ♿✅", "(2,2) → (1,1) PEDESTRIAN ♿✅"); + + var issues = issueStore.listIssues().stream().map(DataImportIssue::getType); + assertThat(issues).containsExactly("FewerThanTwoIntersectionNodesInElevatorWay"); + } +} diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/MoreThanTwoIntersectionsTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/MoreThanTwoIntersectionsTest.java new file mode 100644 index 00000000000..43262257d0f --- /dev/null +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/MoreThanTwoIntersectionsTest.java @@ -0,0 +1,45 @@ +package org.opentripplanner.graph_builder.module.osm.moduletests.elevator; + +import static com.google.common.truth.Truth.assertThat; +import static org.opentripplanner.osm.model.NodeBuilder.node; + +import org.junit.jupiter.api.Test; +import org.opentripplanner.graph_builder.module.osm.OsmModuleTestFactory; +import org.opentripplanner.osm.TestOsmProvider; +import org.opentripplanner.street.geometry.WgsCoordinate; +import org.opentripplanner.street.graph.Graph; +import org.opentripplanner.street.model.edge.ElevatorHopEdge; +import org.opentripplanner.street.model.vertex.ElevatorHopVertex; + +public class MoreThanTwoIntersectionsTest { + + /** + * If an elevator way has three intersection nodes, it is is probably a tagging error. + * OTP supports it anyway. We need to make sure that the middle intersection node is not created + * twice, otherwise we get an error during deserialization. + */ + @Test + void elevatorWayWithThreeIntersectionNodes() { + var n1 = node(1, new WgsCoordinate(1, 1)); + var n2 = node(2, new WgsCoordinate(2, 2)); + var n3 = node(3, new WgsCoordinate(3, 3)); + var n4 = node(4, new WgsCoordinate(4, 4)); + var n5 = node(5, new WgsCoordinate(5, 5)); + + var provider = TestOsmProvider.of() + .addWayFromNodes(way -> way.withTag("highway", "elevator"), n1, n2, n3) + .addWayFromNodes(way -> way.withTag("public_transport", "platform"), n4, n2, n5) + .build(); + var graph = new Graph(); + + OsmModuleTestFactory.of(provider).withGraph(graph).builder().build().buildGraph(); + + var elevatorHopEdges = graph.findEdges(ElevatorHopEdge.class); + assertThat(elevatorHopEdges).hasSize(4); + var elevatorHopVertices = graph + .getVerticesOfType(ElevatorHopVertex.class) + .stream() + .map(vertex -> vertex.getLabelString()); + assertThat(elevatorHopVertices).containsNoDuplicates(); + } +} diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/ElevatorTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/MultipleLevelsTest.java similarity index 60% rename from application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/ElevatorTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/MultipleLevelsTest.java index 6b0912129da..567852b607c 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/ElevatorTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/MultipleLevelsTest.java @@ -4,17 +4,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.osm.model.NodeBuilder.node; -import java.time.Duration; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.StreamSupport; import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; import org.opentripplanner.core.model.accessibility.Accessibility; -import org.opentripplanner.graph_builder.issue.service.DefaultDataImportIssueStore; -import org.opentripplanner.graph_builder.issues.FewerThanTwoIntersectionNodesInElevatorWay; import org.opentripplanner.graph_builder.module.osm.OsmModuleTestFactory; import org.opentripplanner.osm.TestOsmProvider; import org.opentripplanner.osm.model.NodeBuilder; @@ -30,48 +26,10 @@ import org.opentripplanner.street.model.vertex.OsmEntityType; import org.opentripplanner.street.model.vertex.OsmVertex; import org.opentripplanner.streetadapter.VertexFactory; +import org.opentripplanner.utils.collection.ListUtils; +import org.opentripplanner.utils.collection.StreamUtils; -class ElevatorTest { - - @Test - void testDuration() { - var way = OsmWay.of().withTag("duration", "00:01:02").withTag("highway", "elevator").build(); - var provider = TestOsmProvider.of().addWay(way).build(); - var graph = new Graph(); - var osmModule = OsmModuleTestFactory.of(provider).withGraph(graph).builder().build(); - - osmModule.buildGraph(); - - var edges = graph.getEdgesOfType(ElevatorHopEdge.class); - assertThat(edges).hasSize(2); - for (var edge : edges) { - assertThat(edge.getTravelTime()).hasValue(Duration.ofSeconds(62)); - } - } - - @Test - void testMultilevelNodeDuration() { - var node0 = node(0, new WgsCoordinate(0, 0)); - var node1 = node(1, new WgsCoordinate(2, 0)); - var elevatorNode = NodeBuilder.of(2, new WgsCoordinate(1, 0)) - .withTag("duration", "00:01:02") - .withTag("highway", "elevator") - .withTag("level", "1;2") - .build(); - var provider = TestOsmProvider.of() - .addWayFromNodes(way -> way.withTag("level", "1"), node0, elevatorNode) - .addWayFromNodes(way -> way.withTag("level", "2"), node1, elevatorNode) - .build(); - var graph = new Graph(); - - OsmModuleTestFactory.of(provider).withGraph(graph).builder().build().buildGraph(); - - var edges = graph.getEdgesOfType(ElevatorHopEdge.class); - assertThat(edges).hasSize(2); - for (var edge : edges) { - assertThat(edge.getTravelTime()).hasValue(Duration.ofSeconds(62)); - } - } +class MultipleLevelsTest { @Test void testMultilevelNodeWithWaysOnSameLevel() { @@ -89,7 +47,7 @@ void testMultilevelNodeWithWaysOnSameLevel() { OsmModuleTestFactory.of(provider).withGraph(graph).builder().build().buildGraph(); - var edges = graph.getEdgesOfType(ElevatorHopEdge.class); + var edges = ListUtils.ofIterable(graph.findEdges(ElevatorHopEdge.class)); assertThat(edges).hasSize(2); for (var edge : edges) { assertEquals(edge.getLevels(), 0.0); @@ -212,13 +170,15 @@ void testMultilevelNodeWithMultipleWays() { assertEquals(expectedEdgeSet, actualEdgeSet); int streetEdgeCount = 8; - assertEquals(expectedEdgeSet.size() + streetEdgeCount, graph.getEdges().size()); + assertEquals( + expectedEdgeSet.size() + streetEdgeCount, + ListUtils.countIterable(graph.listEdges()) + ); - graph - .getEdgesOfType(ElevatorHopEdge.class) + ListUtils.ofIterable(graph.findEdges(ElevatorHopEdge.class)) .stream() .forEach(edge -> elevatorHopEdgeLevels.put(edge, edge.getLevels())); - for (var edge : graph.getEdgesOfType(ElevatorHopEdge.class)) { + for (var edge : ListUtils.ofIterable(graph.findEdges(ElevatorHopEdge.class))) { assertEquals(edge.getLevels(), elevatorHopEdgeLevels.get(edge)); } } @@ -258,17 +218,10 @@ void testMultilevelWay() { addElevatorBoardAndAlightEdges(edgeSet, osmVertex2, elevatorHopVertex2); addElevatorHopEdges(elevatorHopVertex1, elevatorHopVertex2, 2.5, edgeSet, null); - assertEquals( - edgeSet, - new HashSet<>( - graph - .getEdges() - .stream() - .map(edge -> convertEdgeToVertexLabelString(edge)) - .toList() - ) + var result = StreamSupport.stream(graph.listEdges().spliterator(), false).map(e -> + convertEdgeToVertexLabelString(e) ); - assertEquals(edgeSet.size(), graph.getEdges().size()); + assertThat(result).containsExactlyElementsIn(edgeSet); } @Test @@ -301,128 +254,10 @@ void testMultilevelWayWithoutLevelInfo() { addElevatorBoardAndAlightEdges(edgeSet, osmVertex2, elevatorHopVertex2); addElevatorHopEdges(elevatorHopVertex1, elevatorHopVertex2, 0, edgeSet, null); - assertEquals( - edgeSet, - new HashSet<>( - graph - .getEdges() - .stream() - .map(edge -> convertEdgeToVertexLabelString(edge)) - .toList() - ) - ); - assertEquals(edgeSet.size(), graph.getEdges().size()); - } - - @ParameterizedTest - @CsvSource( - value = { - "1, 2, 3, 4", "1, 1, 1, 1", "0, 1, 1, null", "null, null, 1, null", "null, null, null, null", - }, - nullValues = "null" - ) - void testOsmElevatorNodeUniqueLabels(String level1, String ref1, String level2, String ref2) { - var n1 = node(1, new WgsCoordinate(0, 1)); - var n2 = node(2, new WgsCoordinate(0, 2)); - var elevatorNode = NodeBuilder.of(3, new WgsCoordinate(0, 3)) - .withTag("highway", "elevator") - .build(); - var provider = TestOsmProvider.of() - .addWayFromNodes( - way -> { - way.withTag("level", level1); - way.withTag("level:ref", ref1); - }, - n1, - elevatorNode - ) - .addWayFromNodes( - way -> { - way.withTag("level", level2); - way.withTag("level:ref", ref2); - }, - elevatorNode, - n2 - ) - .build(); - var graph = new Graph(); - - OsmModuleTestFactory.of(provider).withGraph(graph).builder().build().buildGraph(); - - assertEquals( - graph.getVertices().size(), - graph - .getVertices() - .stream() - .map(vertex -> vertex.getLabel()) - .distinct() - .count() + var result = StreamSupport.stream(graph.listEdges().spliterator(), false).map(e -> + convertEdgeToVertexLabelString(e) ); - } - - /** - * If an elevator way has three intersection nodes, it is is probably a tagging error. - * OTP supports it anyway. We need to make sure that the middle intersection node is not created - * twice, otherwise we get an error during deserialization. - */ - @Test - void elevatorWayWithThreeIntersectionNodes() { - var n1 = node(1, new WgsCoordinate(1, 1)); - var n2 = node(2, new WgsCoordinate(2, 2)); - var n3 = node(3, new WgsCoordinate(3, 3)); - var n4 = node(4, new WgsCoordinate(4, 4)); - var n5 = node(5, new WgsCoordinate(5, 5)); - - var provider = TestOsmProvider.of() - .addWayFromNodes(way -> way.withTag("highway", "elevator"), n1, n2, n3) - .addWayFromNodes(way -> way.withTag("public_transport", "platform"), n4, n2, n5) - .build(); - var graph = new Graph(); - - OsmModuleTestFactory.of(provider).withGraph(graph).builder().build().buildGraph(); - - var elevatorHopEdges = graph.getEdgesOfType(ElevatorHopEdge.class); - assertThat(elevatorHopEdges).hasSize(4); - var elevatorHopVertices = graph - .getVerticesOfType(ElevatorHopVertex.class) - .stream() - .map(vertex -> vertex.getLabelString()); - assertThat(elevatorHopVertices).containsNoDuplicates(); - } - - /** - * If the connected nodes of an elevator way have been modeled as elevators, they do not appear - * as intersection nodes. OTP should create an issue, but it should not cause errors. - */ - @Test - void elevatorWayWithFewerThanTwoIntersectionNodes() { - var n1 = NodeBuilder.of(1, new WgsCoordinate(1, 1)).withTag("highway", "elevator").build(); - var n2 = NodeBuilder.of(2, new WgsCoordinate(2, 2)).withTag("highway", "elevator").build(); - - var provider = TestOsmProvider.of() - .addWayFromNodes(way -> way.withTag("highway", "elevator"), n1, n2) - .build(); - var graph = new Graph(); - var issueStore = new DefaultDataImportIssueStore(); - - OsmModuleTestFactory.of(provider) - .withGraph(graph) - .builder() - .withIssueStore(issueStore) - .build() - .buildGraph(); - - var elevatorHopEdges = graph.getEdgesOfType(ElevatorHopEdge.class); - assertThat(elevatorHopEdges).hasSize(0); - - var issues = issueStore - .listIssues() - .stream() - .filter(issue -> issue instanceof FewerThanTwoIntersectionNodesInElevatorWay) - .map(FewerThanTwoIntersectionNodesInElevatorWay.class::cast) - .toList(); - assertEquals(1, issues.size()); - assertEquals(0, issues.getFirst().intersectionNodes()); + assertThat(result).containsExactlyElementsIn(edgeSet); } private void addElevatorBoardAndAlightEdges( @@ -478,23 +313,17 @@ private void addElevatorHopEdges( private Set getActualEdgeSet(Graph graph) { Set actualEdgeSet = new HashSet<>(); actualEdgeSet.addAll( - graph - .getEdgesOfType(ElevatorBoardEdge.class) - .stream() + StreamUtils.ofIterable(graph.findEdges(ElevatorBoardEdge.class)) .map(edge -> convertEdgeToVertexLabelString(edge)) .toList() ); actualEdgeSet.addAll( - graph - .getEdgesOfType(ElevatorAlightEdge.class) - .stream() + StreamUtils.ofIterable(graph.findEdges(ElevatorAlightEdge.class)) .map(edge -> convertEdgeToVertexLabelString(edge)) .toList() ); actualEdgeSet.addAll( - graph - .getEdgesOfType(ElevatorHopEdge.class) - .stream() + StreamUtils.ofIterable(graph.findEdges(ElevatorHopEdge.class)) .map(edge -> convertEdgeToVertexLabelString(edge)) .toList() ); diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/UniqueLabelsTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/UniqueLabelsTest.java new file mode 100644 index 00000000000..418e6ac58f5 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/elevator/UniqueLabelsTest.java @@ -0,0 +1,65 @@ +package org.opentripplanner.graph_builder.module.osm.moduletests.elevator; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.osm.model.NodeBuilder.node; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.opentripplanner.graph_builder.module.osm.OsmModuleTestFactory; +import org.opentripplanner.osm.TestOsmProvider; +import org.opentripplanner.osm.model.NodeBuilder; +import org.opentripplanner.street.geometry.WgsCoordinate; +import org.opentripplanner.street.graph.Graph; + +class UniqueLabelsTest { + + @ParameterizedTest + @CsvSource( + value = { + "1, 2, 3, 4", + "1, 1, 1, 1", + "0, 1, 1, null", + "null, null, 1, null", + "null, null, null, null", + }, + nullValues = "null" + ) + void testOsmElevatorNodeUniqueLabels(String level1, String ref1, String level2, String ref2) { + var n1 = node(1, new WgsCoordinate(0, 1)); + var n2 = node(2, new WgsCoordinate(0, 2)); + var elevatorNode = NodeBuilder.of(3, new WgsCoordinate(0, 3)) + .withTag("highway", "elevator") + .build(); + var provider = TestOsmProvider.of() + .addWayFromNodes( + way -> { + way.withTag("level", level1); + way.withTag("level:ref", ref1); + }, + n1, + elevatorNode + ) + .addWayFromNodes( + way -> { + way.withTag("level", level2); + way.withTag("level:ref", ref2); + }, + elevatorNode, + n2 + ) + .build(); + var graph = new Graph(); + + OsmModuleTestFactory.of(provider).withGraph(graph).builder().build().buildGraph(); + + assertEquals( + graph.getVertices().size(), + graph + .getVertices() + .stream() + .map(vertex -> vertex.getLabel()) + .distinct() + .count() + ); + } +} diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmDatabaseTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/storage/OsmDatabaseTest.java similarity index 99% rename from application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmDatabaseTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/storage/OsmDatabaseTest.java index bc33d1188b8..f3ad9e6910e 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmDatabaseTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/storage/OsmDatabaseTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.storage; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmNodeStoreTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/storage/OsmNodeStoreTest.java similarity index 99% rename from application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmNodeStoreTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/storage/OsmNodeStoreTest.java index b8c8715c481..34c5fe53ae5 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmNodeStoreTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/storage/OsmNodeStoreTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.storage; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmParserTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/storage/OsmParserTest.java similarity index 96% rename from application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmParserTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/storage/OsmParserTest.java index b0337b0f9f1..86d32c0b407 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmParserTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/storage/OsmParserTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.storage; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/VertexGeneratorTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/storage/VertexGeneratorTest.java similarity index 95% rename from application/src/test/java/org/opentripplanner/graph_builder/module/osm/VertexGeneratorTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/storage/VertexGeneratorTest.java index f3e0a9af7da..a5de831dfc6 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/VertexGeneratorTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/storage/VertexGeneratorTest.java @@ -1,11 +1,11 @@ -package org.opentripplanner.graph_builder.module.osm; +package org.opentripplanner.graph_builder.module.osm.storage; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.opentripplanner.graph_builder.module.osm.LinearBarrierNodeType.NORMAL; -import static org.opentripplanner.graph_builder.module.osm.LinearBarrierNodeType.SPLIT; +import static org.opentripplanner.graph_builder.module.osm.model.LinearBarrierNodeType.NORMAL; +import static org.opentripplanner.graph_builder.module.osm.model.LinearBarrierNodeType.SPLIT; import java.util.Comparator; import java.util.Map; diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/stopconnectivity/StopConnectivityModuleTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/stopconnectivity/StopConnectivityModuleTest.java index 91d72f3a52a..a5fa7797fd0 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/stopconnectivity/StopConnectivityModuleTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/stopconnectivity/StopConnectivityModuleTest.java @@ -31,6 +31,7 @@ void stopConnectedToTinyIsland() { StreetModelForTest.streetEdge(i1, i3); var g = new Graph(); + g.hasStreets = true; g.addVertex(stop); g.addVertex(i1); g.addVertex(i2); diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/transfer/DirectTransferGeneratorCarTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/transfer/DirectTransferGeneratorCarTest.java index 14f93e440b9..814622643e5 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/transfer/DirectTransferGeneratorCarTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/transfer/DirectTransferGeneratorCarTest.java @@ -87,10 +87,10 @@ public void testMultipleRequestsWithPatternsAndWithCarsAllowedPatterns() { .build(); String expected_walk_bike_results = """ - S0 - S11, 100m - S0 - S21, 100m - S0 - S22, 200m - S12 - S22, 110m"""; + S0 - S11, 100m + S0 - S21, 100m + S0 - S22, 200m + S12 - S22, 110m"""; assertEquals( expected_walk_bike_results, pathToString(repository.findTransfersByMode(StreetMode.WALK)) @@ -209,7 +209,8 @@ public void testMaxTransferDurationForMode() { assertEquals( """ S0 - S11, 100m - S0 - S21, 100m""".indent(1) + S0 - S21, 100m""" + .indent(1) .stripTrailing(), pathToString(repository.findTransfersByMode(StreetMode.BIKE)) ); diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/transfer/DirectTransferGeneratorTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/transfer/DirectTransferGeneratorTest.java index 0d2f324a014..02bd80911a8 100644 --- a/application/src/test/java/org/opentripplanner/graph_builder/module/transfer/DirectTransferGeneratorTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/transfer/DirectTransferGeneratorTest.java @@ -235,9 +235,9 @@ public void testStreetTransfersWithMultipleRequestsWithPatterns() { // S11, S13, S21 -> * No patterns alight here // * -> S0, S12, S23 No patterns board here String expectedWalkAndBike = """ - S0 - S11, 100m - S0 - S21, 100m - S12 - S22, 110m"""; + S0 - S11, 100m + S0 - S21, 100m + S12 - S22, 110m"""; assertEquals(expectedWalkAndBike, pathToString(walkTransfers)); assertEquals(expectedWalkAndBike, pathToString(bikeTransfers)); assertEquals("", pathToString(carTransfers)); diff --git a/application/src/test/java/org/opentripplanner/inspector/vector/VectorTileResponseFactoryTest.java b/application/src/test/java/org/opentripplanner/inspector/vector/VectorTileResponseFactoryTest.java index ddb7de2772c..75782e70e0a 100644 --- a/application/src/test/java/org/opentripplanner/inspector/vector/VectorTileResponseFactoryTest.java +++ b/application/src/test/java/org/opentripplanner/inspector/vector/VectorTileResponseFactoryTest.java @@ -7,24 +7,13 @@ import java.util.List; import java.util.Locale; import org.junit.jupiter.api.Test; -import org.opentripplanner.ext.fares.service.gtfs.v1.DefaultFareService; import org.opentripplanner.inspector.vector.geofencing.GeofencingZonesLayerBuilder; -import org.opentripplanner.standalone.api.OtpServerRequestContext; -import org.opentripplanner.standalone.api.TestServerContext; -import org.opentripplanner.street.graph.Graph; -import org.opentripplanner.transfer.regular.TransferServiceTestFactory; -import org.opentripplanner.transit.service.TransitRepository; +import org.opentripplanner.service.vehiclerental.VehicleRentalService; +import org.opentripplanner.service.vehiclerental.internal.DefaultVehicleRentalRepository; +import org.opentripplanner.service.vehiclerental.internal.DefaultVehicleRentalService; class VectorTileResponseFactoryTest { - public static final OtpServerRequestContext SERVER_CONTEXT = - TestServerContext.createServerContext( - new Graph(), - new TransitRepository(), - TransferServiceTestFactory.defaultTransferRepository(), - new DefaultFareService() - ); - enum LayerType { RED, GREEN, @@ -45,9 +34,9 @@ public String mapper() { private static LayerBuilder createLayerBuilder( LayerParameters layerParameters, Locale locale, - OtpServerRequestContext context + VehicleRentalService context ) { - return new GeofencingZonesLayerBuilder(context.vehicleRentalService(), layerParameters); + return new GeofencingZonesLayerBuilder(context, layerParameters); } private static Response computeResponse(List layers) { @@ -59,7 +48,7 @@ private static Response computeResponse(List layers) { layers, LAYERS, VectorTileResponseFactoryTest::createLayerBuilder, - SERVER_CONTEXT + new DefaultVehicleRentalService(new DefaultVehicleRentalRepository()) ); } diff --git a/application/src/test/java/org/opentripplanner/kryo/UnmodifiableCollectionsSerializerTest.java b/application/src/test/java/org/opentripplanner/kryo/UnmodifiableCollectionsSerializerTest.java new file mode 100644 index 00000000000..b9da08797c8 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/kryo/UnmodifiableCollectionsSerializerTest.java @@ -0,0 +1,139 @@ +package org.opentripplanner.kryo; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import org.junit.jupiter.api.Test; + +class UnmodifiableCollectionsSerializerTest { + + private final Kryo kryo = newKryo(); + + @Test + void roundTripUnmodifiableCollection() { + var original = Collections.unmodifiableCollection(Arrays.asList("a", "b", "c")); + var result = roundTrip(original); + assertThat(result).containsExactly("a", "b", "c"); + assertThrows(UnsupportedOperationException.class, () -> result.add("d")); + } + + @Test + void roundTripUnmodifiableRandomAccessList() { + var original = Collections.unmodifiableList(new ArrayList<>(List.of("a", "b", "c"))); + var result = roundTrip(original); + assertThat(result).containsExactly("a", "b", "c").inOrder(); + assertThrows(UnsupportedOperationException.class, () -> result.add("d")); + } + + @Test + void roundTripUnmodifiableList() { + var original = Collections.unmodifiableList(new LinkedList<>(List.of("a", "b", "c"))); + var result = roundTrip(original); + assertThat(result).containsExactly("a", "b", "c").inOrder(); + assertThrows(UnsupportedOperationException.class, () -> result.add("d")); + } + + @Test + void roundTripUnmodifiableSet() { + var original = Collections.unmodifiableSet(new HashSet<>(Set.of("a", "b", "c"))); + var result = roundTrip(original); + assertThat(result).containsExactly("a", "b", "c"); + assertThrows(UnsupportedOperationException.class, () -> result.add("d")); + } + + @Test + void roundTripUnmodifiableSortedSet() { + var original = Collections.unmodifiableSortedSet(new TreeSet<>(Set.of("c", "a", "b"))); + var result = roundTrip(original); + assertThat(new ArrayList<>(result)).containsExactly("a", "b", "c").inOrder(); + assertThrows(UnsupportedOperationException.class, () -> result.add("d")); + } + + @Test + void writeRejectsSortedSetWithCustomComparator() { + var original = Collections.unmodifiableSortedSet( + new TreeSet<>(Comparator.reverseOrder()) + ); + assertThrows(UnsupportedOperationException.class, () -> roundTrip(original)); + } + + @Test + void roundTripUnmodifiableMap() { + var original = Collections.unmodifiableMap(new HashMap<>(Map.of("a", 1, "b", 2))); + var result = roundTrip(original); + assertThat(result).containsExactly("a", 1, "b", 2); + assertThrows(UnsupportedOperationException.class, () -> result.put("c", 3)); + } + + @Test + void roundTripUnmodifiableSortedMap() { + var source = new TreeMap(); + source.put("c", 3); + source.put("a", 1); + source.put("b", 2); + var original = Collections.unmodifiableSortedMap(source); + var result = roundTrip(original); + assertThat(new ArrayList<>(result.keySet())).containsExactly("a", "b", "c").inOrder(); + assertThat(result).containsExactly("a", 1, "b", 2, "c", 3); + assertThrows(UnsupportedOperationException.class, () -> result.put("d", 4)); + } + + @Test + void writeRejectsSortedMapWithCustomComparator() { + var original = Collections.unmodifiableSortedMap( + new TreeMap(Comparator.reverseOrder()) + ); + assertThrows(UnsupportedOperationException.class, () -> roundTrip(original)); + } + + @Test + void copyPreservesUnmodifiabilityAndContents() { + Map original = Collections.unmodifiableMap(new HashMap<>(Map.of("a", 1))); + Map copy = kryo.copy(original); + assertThat(copy).containsExactly("a", 1); + assertThrows(UnsupportedOperationException.class, () -> copy.put("b", 2)); + } + + @Test + void writeRejectsUnsupportedType() { + var serializer = new UnmodifiableCollectionsSerializer(); + try (Output output = new Output(64, -1)) { + assertThrows(IllegalArgumentException.class, () -> + serializer.write(kryo, output, "not a wrapped collection") + ); + } + } + + private static Kryo newKryo() { + Kryo kryo = new Kryo(); + kryo.setRegistrationRequired(false); + UnmodifiableCollectionsSerializer.registerSerializers(kryo); + return kryo; + } + + @SuppressWarnings("unchecked") + private T roundTrip(T original) { + try (Output output = new Output(256, -1)) { + kryo.writeClassAndObject(output, original); + output.flush(); + try (Input input = new Input(output.toBytes())) { + return (T) kryo.readClassAndObject(input); + } + } + } +} diff --git a/application/src/test/java/org/opentripplanner/mmri/BeneficialChangesTest.java b/application/src/test/java/org/opentripplanner/mmri/BeneficialChangesTest.java index 6d5176feb88..f6d9f7ffb96 100644 --- a/application/src/test/java/org/opentripplanner/mmri/BeneficialChangesTest.java +++ b/application/src/test/java/org/opentripplanner/mmri/BeneficialChangesTest.java @@ -20,7 +20,7 @@ public void test3c1() { Leg leg = itinerary.legs().toArray(new Leg[1])[0]; - validateLeg(leg, 1388531040000L, 1388531100000L, "3c3", "3c2", null); + validateLeg(leg, 1388531040000L, 1388531100000L, "3c3", "3c2"); assertEquals("Stop 3c2 ~ BUS bus 0:04 0:05 ~ Stop 3c3 [C₁90]", itinerary.toStr()); } diff --git a/application/src/test/java/org/opentripplanner/mmri/ExcludedRoutesTest.java b/application/src/test/java/org/opentripplanner/mmri/ExcludedRoutesTest.java index 7e4b6cd7ee0..9c34d4660e6 100644 --- a/application/src/test/java/org/opentripplanner/mmri/ExcludedRoutesTest.java +++ b/application/src/test/java/org/opentripplanner/mmri/ExcludedRoutesTest.java @@ -20,7 +20,7 @@ public void test3d1() { Leg leg = itinerary.legs().toArray(new Leg[1])[0]; - validateLeg(leg, 1388530860000L, 1388530980000L, "3d2", "3d1", null); + validateLeg(leg, 1388530860000L, 1388530980000L, "3d2", "3d1"); assertEquals("Stop 3d1 ~ BUS bus 2 0:01 0:03 ~ Stop 3d2 [C₁150]", itinerary.toStr()); } diff --git a/application/src/test/java/org/opentripplanner/mmri/ExcludedTripsTest.java b/application/src/test/java/org/opentripplanner/mmri/ExcludedTripsTest.java index d8fb9617715..a20b2620c67 100644 --- a/application/src/test/java/org/opentripplanner/mmri/ExcludedTripsTest.java +++ b/application/src/test/java/org/opentripplanner/mmri/ExcludedTripsTest.java @@ -20,7 +20,7 @@ public void test3e1() { Leg leg = itinerary.legs().toArray(new Leg[1])[0]; - validateLeg(leg, 1388530980000L, 1388531040000L, "3e2", "3e1", null); + validateLeg(leg, 1388530980000L, 1388531040000L, "3e2", "3e1"); assertEquals("Stop 3e1 ~ BUS bus 0:03 0:04 ~ Stop 3e2 [C₁90]", itinerary.toStr()); } diff --git a/application/src/test/java/org/opentripplanner/mmri/FirstForbiddenTripToTripTransferTest.java b/application/src/test/java/org/opentripplanner/mmri/FirstForbiddenTripToTripTransferTest.java index 2ffa2e9c493..bf543dce381 100644 --- a/application/src/test/java/org/opentripplanner/mmri/FirstForbiddenTripToTripTransferTest.java +++ b/application/src/test/java/org/opentripplanner/mmri/FirstForbiddenTripToTripTransferTest.java @@ -20,8 +20,8 @@ public void test2e3() { Leg[] legs = itinerary.legs().toArray(new Leg[2]); - validateLeg(legs[0], 1388530860000L, 1388530980000L, "2e34", "2e31", null); - validateLeg(legs[1], 1388531040000L, 1388531100000L, "2e36", "2e34", null); + validateLeg(legs[0], 1388530860000L, 1388530980000L, "2e34", "2e31"); + validateLeg(legs[1], 1388531040000L, 1388531100000L, "2e36", "2e34"); assertEquals( "Stop 2e31 ~ RAIL train 1 0:01 0:03 ~ Stop 2e34 ~ RAIL train 2 0:04 0:05 ~ Stop 2e36 [C₁300]", diff --git a/application/src/test/java/org/opentripplanner/mmri/FirstPreferredTripToTripTransferTest.java b/application/src/test/java/org/opentripplanner/mmri/FirstPreferredTripToTripTransferTest.java index d347d7c6d4b..ebf69bddb31 100644 --- a/application/src/test/java/org/opentripplanner/mmri/FirstPreferredTripToTripTransferTest.java +++ b/application/src/test/java/org/opentripplanner/mmri/FirstPreferredTripToTripTransferTest.java @@ -20,8 +20,8 @@ public void test2e1() { Leg[] legs = itinerary.legs().toArray(new Leg[2]); - validateLeg(legs[0], 1388530860000L, 1388530920000L, "2e13", "2e11", null); - validateLeg(legs[1], 1388530980000L, 1388531100000L, "2e16", "2e13", null); + validateLeg(legs[0], 1388530860000L, 1388530920000L, "2e13", "2e11"); + validateLeg(legs[1], 1388530980000L, 1388531100000L, "2e16", "2e13"); assertEquals( "Stop 2e11 ~ RAIL train 1 0:01 0:02 ~ Stop 2e13 ~ RAIL train 2 0:03 0:05 ~ Stop 2e16 [C₁270]", diff --git a/application/src/test/java/org/opentripplanner/mmri/FirstUnpreferredTransferTest.java b/application/src/test/java/org/opentripplanner/mmri/FirstUnpreferredTransferTest.java index 2005374bad3..1bd3ffac02b 100644 --- a/application/src/test/java/org/opentripplanner/mmri/FirstUnpreferredTransferTest.java +++ b/application/src/test/java/org/opentripplanner/mmri/FirstUnpreferredTransferTest.java @@ -20,8 +20,8 @@ public void test3g1() { Leg[] legs = itinerary.legs().toArray(new Leg[2]); - validateLeg(legs[0], 1388530860000L, 1388530980000L, "3g14", "3g11", null); - validateLeg(legs[1], 1388531040000L, 1388531100000L, "3g16", "3g14", null); + validateLeg(legs[0], 1388530860000L, 1388530980000L, "3g14", "3g11"); + validateLeg(legs[1], 1388531040000L, 1388531100000L, "3g16", "3g14"); assertEquals( "Stop 3g11 ~ RAIL train 1 0:01 0:03 ~ Stop 3g14 ~ RAIL train 2 0:04 0:05 ~ Stop 3g16 [C₁300]", diff --git a/application/src/test/java/org/opentripplanner/mmri/OptimizationTest.java b/application/src/test/java/org/opentripplanner/mmri/OptimizationTest.java index 49b96f6328e..762ad5c3d78 100644 --- a/application/src/test/java/org/opentripplanner/mmri/OptimizationTest.java +++ b/application/src/test/java/org/opentripplanner/mmri/OptimizationTest.java @@ -20,7 +20,7 @@ public void test2a1() { Leg leg = itinerary.legs().toArray(new Leg[1])[0]; - validateLeg(leg, 1388530860000L, 1388530920000L, "2a2", "2a1", null); + validateLeg(leg, 1388530860000L, 1388530920000L, "2a2", "2a1"); assertEquals("Stop 2a1 ~ BUS short 0:01 0:02 ~ Stop 2a2 [C₁90]", itinerary.toStr()); } @@ -31,7 +31,7 @@ public void test2a2() { Leg leg = itinerary.legs().toArray(new Leg[1])[0]; - validateLeg(leg, 1388531100000L, 1388531160000L, "2a2", "2a1", null); + validateLeg(leg, 1388531100000L, 1388531160000L, "2a2", "2a1"); assertEquals("Stop 2a1 ~ BUS long 0:05 0:06 ~ Stop 2a2 [C₁90]", itinerary.toStr()); } diff --git a/application/src/test/java/org/opentripplanner/mmri/PreferencesTest.java b/application/src/test/java/org/opentripplanner/mmri/PreferencesTest.java index a40d775ee02..2cad21d38fc 100644 --- a/application/src/test/java/org/opentripplanner/mmri/PreferencesTest.java +++ b/application/src/test/java/org/opentripplanner/mmri/PreferencesTest.java @@ -20,8 +20,8 @@ public void test2c1() { Leg[] legs = itinerary.legs().toArray(new Leg[2]); - validateLeg(legs[0], 1388530860000L, 1388530920000L, "2c2", "2c1", null); - validateLeg(legs[1], 1388530980000L, 1388531040000L, "2c3", "2c2", null); + validateLeg(legs[0], 1388530860000L, 1388530920000L, "2c2", "2c1"); + validateLeg(legs[1], 1388530980000L, 1388531040000L, "2c3", "2c2"); assertEquals( "Stop 2c1 ~ RAIL train 1 0:01 0:02 ~ Stop 2c2 ~ RAIL train 2 0:03 0:04 ~ Stop 2c3 [C₁240]", diff --git a/application/src/test/java/org/opentripplanner/mmri/SecondForbiddenTripToTripTransferTest.java b/application/src/test/java/org/opentripplanner/mmri/SecondForbiddenTripToTripTransferTest.java index e5177addeb7..eaa3eee8156 100644 --- a/application/src/test/java/org/opentripplanner/mmri/SecondForbiddenTripToTripTransferTest.java +++ b/application/src/test/java/org/opentripplanner/mmri/SecondForbiddenTripToTripTransferTest.java @@ -20,8 +20,8 @@ public void test2e4() { Leg[] legs = itinerary.legs().toArray(new Leg[2]); - validateLeg(legs[0], 1388530860000L, 1388530920000L, "2e43", "2e41", null); - validateLeg(legs[1], 1388530980000L, 1388531100000L, "2e46", "2e43", null); + validateLeg(legs[0], 1388530860000L, 1388530920000L, "2e43", "2e41"); + validateLeg(legs[1], 1388530980000L, 1388531100000L, "2e46", "2e43"); assertEquals( "Stop 2e41 ~ RAIL train 1 0:01 0:02 ~ Stop 2e43 ~ RAIL train 2 0:03 0:05 ~ Stop 2e46 [C₁300]", diff --git a/application/src/test/java/org/opentripplanner/mmri/SecondPreferredTripToTripTransferTest.java b/application/src/test/java/org/opentripplanner/mmri/SecondPreferredTripToTripTransferTest.java index d6e83889c27..fe3fc79f6f5 100644 --- a/application/src/test/java/org/opentripplanner/mmri/SecondPreferredTripToTripTransferTest.java +++ b/application/src/test/java/org/opentripplanner/mmri/SecondPreferredTripToTripTransferTest.java @@ -20,8 +20,8 @@ public void test2e2() { Leg[] legs = itinerary.legs().toArray(new Leg[2]); - validateLeg(legs[0], 1388530860000L, 1388530980000L, "2e24", "2e21", null); - validateLeg(legs[1], 1388531040000L, 1388531100000L, "2e26", "2e24", null); + validateLeg(legs[0], 1388530860000L, 1388530980000L, "2e24", "2e21"); + validateLeg(legs[1], 1388531040000L, 1388531100000L, "2e26", "2e24"); assertEquals( "Stop 2e21 ~ RAIL train 1 0:01 0:03 ~ Stop 2e24 ~ RAIL train 2 0:04 0:05 ~ Stop 2e26 [C₁270]", diff --git a/application/src/test/java/org/opentripplanner/mmri/SecondUnpreferredTransferTest.java b/application/src/test/java/org/opentripplanner/mmri/SecondUnpreferredTransferTest.java index 63ccd76d2ca..27368ba7894 100644 --- a/application/src/test/java/org/opentripplanner/mmri/SecondUnpreferredTransferTest.java +++ b/application/src/test/java/org/opentripplanner/mmri/SecondUnpreferredTransferTest.java @@ -20,8 +20,8 @@ public void test3g2() { Leg[] legs = itinerary.legs().toArray(new Leg[2]); - validateLeg(legs[0], 1388530860000L, 1388530920000L, "3g23", "3g21", null); - validateLeg(legs[1], 1388530980000L, 1388531100000L, "3g26", "3g23", null); + validateLeg(legs[0], 1388530860000L, 1388530920000L, "3g23", "3g21"); + validateLeg(legs[1], 1388530980000L, 1388531100000L, "3g26", "3g23"); assertEquals( "Stop 3g21 ~ RAIL train 1 0:01 0:02 ~ Stop 3g23 ~ RAIL train 2 0:03 0:05 ~ Stop 3g26 [C₁300]", diff --git a/application/src/test/java/org/opentripplanner/mmri/StopToStopTransfersTest.java b/application/src/test/java/org/opentripplanner/mmri/StopToStopTransfersTest.java index d4d305d97cb..78a05f252c1 100644 --- a/application/src/test/java/org/opentripplanner/mmri/StopToStopTransfersTest.java +++ b/application/src/test/java/org/opentripplanner/mmri/StopToStopTransfersTest.java @@ -20,8 +20,8 @@ public void test2d1() { Leg[] legs = itinerary.legs().toArray(new Leg[2]); - validateLeg(legs[0], 1388530860000L, 1388530980000L, "2d3", "2d1", null); - validateLeg(legs[1], 1388530980000L, 1388531040000L, "2d4", "2d3", null); + validateLeg(legs[0], 1388530860000L, 1388530980000L, "2d3", "2d1"); + validateLeg(legs[1], 1388530980000L, 1388531040000L, "2d4", "2d3"); assertEquals( "Stop 2d1 ~ RAIL train 1 0:01 0:03 ~ Stop 2d3 ~ RAIL train 2 0:03 0:04 ~ Stop 2d4 [C₁210]", diff --git a/application/src/test/java/org/opentripplanner/mmri/TimeTest.java b/application/src/test/java/org/opentripplanner/mmri/TimeTest.java index 995e3b60d5b..f623eac06cf 100644 --- a/application/src/test/java/org/opentripplanner/mmri/TimeTest.java +++ b/application/src/test/java/org/opentripplanner/mmri/TimeTest.java @@ -20,7 +20,7 @@ public void test1g1() { Leg leg = itinerary.legs().toArray(new Leg[1])[0]; - validateLeg(leg, 1388530980000L, 1388531040000L, "1g2", "1g1", null); + validateLeg(leg, 1388530980000L, 1388531040000L, "1g2", "1g1"); assertEquals("Stop 1g1 ~ BUS bus 0:03 0:04 ~ Stop 1g2 [C₁90]", itinerary.toStr()); } @@ -31,7 +31,7 @@ public void test1g2() { Leg leg = itinerary.legs().toArray(new Leg[1])[0]; - validateLeg(leg, 1388530860000L, 1388530920000L, "1g2", "1g1", null); + validateLeg(leg, 1388530860000L, 1388530920000L, "1g2", "1g1"); assertEquals("Stop 1g1 ~ BUS bus 0:01 0:02 ~ Stop 1g2 [C₁90]", itinerary.toStr()); } @@ -42,7 +42,7 @@ public void test1g5() { Leg leg = itinerary.legs().toArray(new Leg[1])[0]; - validateLeg(leg, 1388703780000L, 1388703840000L, "1g2", "1g1", null); + validateLeg(leg, 1388703780000L, 1388703840000L, "1g2", "1g1"); assertEquals("Stop 1g1 ~ BUS bus 0:03 0:04 ~ Stop 1g2 [C₁90]", itinerary.toStr()); } @@ -53,7 +53,7 @@ public void test1g6() { Leg leg = itinerary.legs().toArray(new Leg[1])[0]; - validateLeg(leg, 1388703660000L, 1388703720000L, "1g2", "1g1", null); + validateLeg(leg, 1388703660000L, 1388703720000L, "1g2", "1g1"); assertEquals("Stop 1g1 ~ BUS bus 0:01 0:02 ~ Stop 1g2 [C₁90]", itinerary.toStr()); } diff --git a/application/src/test/java/org/opentripplanner/mmri/UnplannedChangesTest.java b/application/src/test/java/org/opentripplanner/mmri/UnplannedChangesTest.java index 01fee757591..7ba220c2f6e 100644 --- a/application/src/test/java/org/opentripplanner/mmri/UnplannedChangesTest.java +++ b/application/src/test/java/org/opentripplanner/mmri/UnplannedChangesTest.java @@ -20,7 +20,7 @@ public void test3b1() { Leg leg = itinerary.legs().toArray(new Leg[1])[0]; - validateLeg(leg, 1388531460000L, 1388531520000L, "3b2", "3b1", null); + validateLeg(leg, 1388531460000L, 1388531520000L, "3b2", "3b1"); assertEquals("Stop 3b1 ~ BUS bus 0:11 0:12 ~ Stop 3b2 [C₁90]", itinerary.toStr()); } @@ -31,7 +31,7 @@ public void test3b2() { Leg leg = itinerary.legs().toArray(new Leg[1])[0]; - validateLeg(leg, 1388531460000L, 1388531520000L, "3b2", "3b1", null); + validateLeg(leg, 1388531460000L, 1388531520000L, "3b2", "3b1"); assertEquals("Stop 3b1 ~ BUS bus 0:11 0:12 ~ Stop 3b2 [C₁90]", itinerary.toStr()); } diff --git a/application/src/test/java/org/opentripplanner/mmri/WheelchairTest.java b/application/src/test/java/org/opentripplanner/mmri/WheelchairTest.java index 18affef9651..28269897d68 100644 --- a/application/src/test/java/org/opentripplanner/mmri/WheelchairTest.java +++ b/application/src/test/java/org/opentripplanner/mmri/WheelchairTest.java @@ -17,7 +17,7 @@ public final String getFeedName() { public void test2b1() { Itinerary itinerary = plan(+1388530860L, "2b1", "2b2", true, false, null, "", "", 1); - validateLeg(itinerary.legs().getFirst(), 1388530980000L, 1388531040000L, "2b2", "2b1", null); + validateLeg(itinerary.legs().getFirst(), 1388530980000L, 1388531040000L, "2b2", "2b1"); assertEquals("Stop 2b1 ~ BUS attr 0:03 0:04 ~ Stop 2b2 [C₁90]", itinerary.toStr()); } diff --git a/application/src/test/java/org/opentripplanner/model/TripTimeOnDateTest.java b/application/src/test/java/org/opentripplanner/model/TripTimeOnDateTest.java index 02a4b6acb46..56c4c9c2e6a 100644 --- a/application/src/test/java/org/opentripplanner/model/TripTimeOnDateTest.java +++ b/application/src/test/java/org/opentripplanner/model/TripTimeOnDateTest.java @@ -15,7 +15,7 @@ import org.opentripplanner.routing.algorithm.raptoradapter.transit.RaptorTransitDataTestFactory; import org.opentripplanner.transit.model._data.TransitRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; -import org.opentripplanner.transit.model.calendar.DefaultTripCalendars; +import org.opentripplanner.transit.model.calendar.TripCalendars; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.timetable.ScheduledTripTimes; import org.opentripplanner.transit.model.timetable.Timetable; @@ -189,7 +189,7 @@ void testFromTripTimesWithScheduleFallback() { transitRepository.index(); var timetableSnapshot = new DefaultTimetableRepository( RaptorTransitDataTestFactory.empty(), - new DefaultTripCalendars() + TripCalendars.empty() ); timetableSnapshot.commit(); var serviceDate = LocalDate.of(2025, 1, 1); diff --git a/application/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java b/application/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java index d10a865cf07..93b92ec1097 100644 --- a/application/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java +++ b/application/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java @@ -118,7 +118,7 @@ void testDerivedFieldsWithWalAccessAndTwoTransitLegs() { assertEquals(ofMinutes(28), itinerary.totalDuration()); assertEquals(ofMinutes(20), itinerary.totalTransitDuration()); assertEquals(ofMinutes(1), itinerary.totalStreetDuration()); - assertEquals(ofMinutes((2 + 5)), itinerary.totalWaitingDuration()); + assertEquals(ofMinutes(2 + 5), itinerary.totalWaitingDuration()); // Cost: walk + wait + board + transit = 2 * 60 + .8 * 420 + 2 * 120 + 1200 assertEquals(1896, itinerary.generalizedCost()); diff --git a/application/src/test/java/org/opentripplanner/model/plan/TestItineraryBuilder.java b/application/src/test/java/org/opentripplanner/model/plan/TestItineraryBuilder.java index 10a745df1ab..34db7626b13 100644 --- a/application/src/test/java/org/opentripplanner/model/plan/TestItineraryBuilder.java +++ b/application/src/test/java/org/opentripplanner/model/plan/TestItineraryBuilder.java @@ -152,7 +152,7 @@ public TestItineraryBuilder drive(int startTime, int endTime, Place to) { public TestItineraryBuilder rentedBicycle(int startTime, int endTime, Place to) { int legCost = cost(BICYCLE_RELUCTANCE_FACTOR, endTime - startTime); streetLeg(BICYCLE, startTime, endTime, to, legCost, List.of()); - var leg = ((StreetLeg) this.legs.get(0)); + var leg = (StreetLeg) this.legs.get(0); var updatedLeg = leg.copyOf().withRentedVehicle(true).build(); this.legs.add(0, updatedLeg); return this; diff --git a/application/src/test/java/org/opentripplanner/model/plan/legreference/ScheduledTransitLegReferenceTest.java b/application/src/test/java/org/opentripplanner/model/plan/legreference/ScheduledTransitLegReferenceTest.java index 751bac76617..2b9b0028cc8 100644 --- a/application/src/test/java/org/opentripplanner/model/plan/legreference/ScheduledTransitLegReferenceTest.java +++ b/application/src/test/java/org/opentripplanner/model/plan/legreference/ScheduledTransitLegReferenceTest.java @@ -98,7 +98,7 @@ static void buildTransitService() { .withScheduledTimeTableBuilder(builder -> builder.addTripTimes(tripTimes)) .build(); transitRepository.addTripPattern(tripPattern.getId(), tripPattern); - transitRepository.getServiceCodes().put(tripPattern.getId(), SERVICE_CODE); + transitRepository.putServiceCode(tripPattern.getId(), SERVICE_CODE); FeedScopedId tripOnServiceDateId = id("TRIP_ON_SERVICE_DATE" + item.getKey().getId()); transitRepository.addTripOnServiceDate( TripOnServiceDate.of(tripOnServiceDateId) diff --git a/application/src/test/java/org/opentripplanner/netex/mapping/NetexMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/NetexMapperTest.java index cd8d830b0b9..7727f58289c 100644 --- a/application/src/test/java/org/opentripplanner/netex/mapping/NetexMapperTest.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/NetexMapperTest.java @@ -20,8 +20,9 @@ class NetexMapperTest { private static final String QUAY_ID = "quay-1"; private static final String SSP_ID = "ssp-1"; private static final String FEED_ID = "sta"; - private static final RegularStop STOP = RegularStop.of(new FeedScopedId(FEED_ID, QUAY_ID), () -> - 1 + private static final RegularStop STOP = RegularStop.of( + new FeedScopedId(FEED_ID, QUAY_ID), + () -> 1 ).build(); private static final Deduplicator DEDUPLICATOR = new Deduplicator(); diff --git a/application/src/test/java/org/opentripplanner/netex/validation/ServiceJourneyNonIncreasingPassingTimeTest.java b/application/src/test/java/org/opentripplanner/netex/validation/ServiceJourneyNonIncreasingPassingTimeTest.java index 45d9d53bec4..d344517c8f6 100644 --- a/application/src/test/java/org/opentripplanner/netex/validation/ServiceJourneyNonIncreasingPassingTimeTest.java +++ b/application/src/test/java/org/opentripplanner/netex/validation/ServiceJourneyNonIncreasingPassingTimeTest.java @@ -475,7 +475,8 @@ private String getScheduledStopPointRef( .getPointsInSequence() .getPointInJourneyPatternOrStopPointInJourneyPatternOrTimingPointInJourneyPattern() .get(order) - ).getScheduledStopPointRef() + ) + .getScheduledStopPointRef() .getValue() .getRef(); } diff --git a/application/src/test/java/org/opentripplanner/osm/model/CompoundRefTagGroupTest.java b/application/src/test/java/org/opentripplanner/osm/model/CompoundRefTagGroupTest.java new file mode 100644 index 00000000000..b1a356dd6e3 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/osm/model/CompoundRefTagGroupTest.java @@ -0,0 +1,63 @@ +package org.opentripplanner.osm.model; + +import static com.google.common.truth.Truth.assertThat; + +import java.util.Map; +import org.junit.jupiter.api.Test; + +public class CompoundRefTagGroupTest { + + @Test + void compoundValueSingleTag() { + var group = CompoundRefTagGroup.of("ref"); + var tags = Map.of("ref", "E1"); + + assertThat(group.compoundValue(tags::get)).hasValue("E1"); + } + + @Test + void compoundValueJoinsMultipleTagsWithColon() { + var group = CompoundRefTagGroup.of("manufacturer", "ref"); + var tags = Map.of("manufacturer", "KONE", "ref", "12345"); + + assertThat(group.compoundValue(tags::get)).hasValue("KONE:12345"); + } + + @Test + void compoundValueEmptyWhenAnyTagMissing() { + var group = CompoundRefTagGroup.of("manufacturer", "ref"); + var tags = Map.of("ref", "12345"); + + assertThat(group.compoundValue(tags::get)).isEmpty(); + } + + @Test + void compoundValueStripsWhitespaceFromResolvedValues() { + var group = CompoundRefTagGroup.of("manufacturer", "ref"); + var tags = Map.of("manufacturer", " KONE ", "ref", " 12345 "); + + assertThat(group.compoundValue(tags::get)).hasValue("KONE:12345"); + } + + @Test + void ofFiltersNullAndBlankTags() { + var group = CompoundRefTagGroup.of("ref", null, " ", "manufacturer"); + var tags = Map.of("ref", "12345", "manufacturer", "KONE"); + + assertThat(group.compoundValue(tags::get)).hasValue("12345:KONE"); + } + + @Test + void equalsAndHashCode() { + assertThat(CompoundRefTagGroup.of("manufacturer", "ref")).isEqualTo( + CompoundRefTagGroup.of("manufacturer", "ref") + ); + assertThat(CompoundRefTagGroup.of("manufacturer", "ref").hashCode()).isEqualTo( + CompoundRefTagGroup.of("manufacturer", "ref").hashCode() + ); + assertThat(CompoundRefTagGroup.of("manufacturer", "ref")).isNotEqualTo( + CompoundRefTagGroup.of("ref", "manufacturer") + ); + assertThat(CompoundRefTagGroup.of("ref")).isNotEqualTo(CompoundRefTagGroup.of("manufacturer")); + } +} diff --git a/application/src/test/java/org/opentripplanner/osm/model/OsmEntityTest.java b/application/src/test/java/org/opentripplanner/osm/model/OsmEntityTest.java index e3318e51eaf..7a583b61652 100644 --- a/application/src/test/java/org/opentripplanner/osm/model/OsmEntityTest.java +++ b/application/src/test/java/org/opentripplanner/osm/model/OsmEntityTest.java @@ -1,5 +1,6 @@ package org.opentripplanner.osm.model; +import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; @@ -220,6 +221,37 @@ void shouldNotReturnNull() { assertEquals(Set.of(), osm.getMultiTagValues(Set.of("ref3"))); } + @Test + void getCompoundTagValueSingleTagGroup() { + var osm = new OsmTestEntity("ref", "E1"); + + assertThat(osm.getCompoundTagValue(List.of(CompoundRefTagGroup.of("ref")))).hasValue("E1"); + } + + @Test + void getCompoundTagValueUsesFirstGroupThatResolvesAndSkipsMissingTags() { + var osm = new OsmTestEntity(Map.of("manufacturer", "KONE", "ref", "12345")); + + assertThat( + osm.getCompoundTagValue( + List.of( + CompoundRefTagGroup.of("missing"), + CompoundRefTagGroup.of("manufacturer", "ref"), + CompoundRefTagGroup.of("ref") + ) + ) + ).hasValue("KONE:12345"); + } + + @Test + void getCompoundTagValueEmptyWhenNoGroupResolves() { + var osm = new OsmTestEntity("ref", "12345"); + + assertThat( + osm.getCompoundTagValue(List.of(CompoundRefTagGroup.of("manufacturer", "ref"))) + ).isEmpty(); + } + @Test void isWheelchairAccessible() { var osm1 = new OsmTestEntity(); diff --git a/application/src/test/java/org/opentripplanner/osm/tagmapping/OsmTagMapperTest.java b/application/src/test/java/org/opentripplanner/osm/tagmapping/OsmTagMapperTest.java index 79797f41592..4974da29a56 100644 --- a/application/src/test/java/org/opentripplanner/osm/tagmapping/OsmTagMapperTest.java +++ b/application/src/test/java/org/opentripplanner/osm/tagmapping/OsmTagMapperTest.java @@ -532,6 +532,6 @@ public OsmEntity way(String key, String value) { * Test that two values are within epsilon of each other. */ private boolean within(float val1, float val2, float epsilon) { - return (Math.abs(val1 - val2) < epsilon); + return Math.abs(val1 - val2) < epsilon; } } diff --git a/application/src/test/java/org/opentripplanner/osm/wayproperty/OverridePermissionsTest.java b/application/src/test/java/org/opentripplanner/osm/wayproperty/OverridePermissionsTest.java index 27bb3d9ce58..9219f60d15e 100644 --- a/application/src/test/java/org/opentripplanner/osm/wayproperty/OverridePermissionsTest.java +++ b/application/src/test/java/org/opentripplanner/osm/wayproperty/OverridePermissionsTest.java @@ -3,7 +3,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -import org.opentripplanner.graph_builder.module.osm.StreetTraversalPermissionPair; import org.opentripplanner.osm.model.OsmWay; import org.opentripplanner.street.model.StreetTraversalPermission; @@ -158,4 +157,9 @@ private StreetTraversalPermissionPair getWayProperties(OsmWay way) { wayData.backward().getPermission() ); } + + private record StreetTraversalPermissionPair( + StreetTraversalPermission main, + StreetTraversalPermission back + ) {} } diff --git a/application/src/test/java/org/opentripplanner/place/nearbystopfinder/StreetNearbyStopFinderTest.java b/application/src/test/java/org/opentripplanner/place/nearbystopfinder/StreetNearbyStopFinderTest.java index a6c5b63507f..4cd12f56e10 100644 --- a/application/src/test/java/org/opentripplanner/place/nearbystopfinder/StreetNearbyStopFinderTest.java +++ b/application/src/test/java/org/opentripplanner/place/nearbystopfinder/StreetNearbyStopFinderTest.java @@ -229,7 +229,10 @@ void testIgnoreStopsWithMaxStops() { } static List sort(Collection stops) { - return stops.stream().sorted(Comparator.comparing(x -> x.distance)).toList(); + return stops + .stream() + .sorted(Comparator.comparing(x -> x.distance)) + .toList(); } /** diff --git a/application/src/test/java/org/opentripplanner/place/placefinder/PlaceFinderTraverseVisitorTest.java b/application/src/test/java/org/opentripplanner/place/placefinder/PlaceFinderTraverseVisitorTest.java index 4d4529aa1dc..43e8a5c440d 100644 --- a/application/src/test/java/org/opentripplanner/place/placefinder/PlaceFinderTraverseVisitorTest.java +++ b/application/src/test/java/org/opentripplanner/place/placefinder/PlaceFinderTraverseVisitorTest.java @@ -56,7 +56,10 @@ public class PlaceFinderTraverseVisitorTest { static final Route R = route("r").build(); static final TransitRepository TIMETABLE_REPO = new TransitRepository( - model.siteRepositoryBuilder().withRegularStops(List.of(STOP1, STOP2, STOP3, STOP4)).build() + model + .siteRepositoryBuilder() + .withRegularStops(List.of(STOP1, STOP2, STOP3, STOP4)) + .build() ); static { diff --git a/application/src/test/java/org/opentripplanner/place/placefinder/StreetNearbyPlaceFinderTest.java b/application/src/test/java/org/opentripplanner/place/placefinder/StreetNearbyPlaceFinderTest.java index 09e1a8370d8..bf327592e5c 100644 --- a/application/src/test/java/org/opentripplanner/place/placefinder/StreetNearbyPlaceFinderTest.java +++ b/application/src/test/java/org/opentripplanner/place/placefinder/StreetNearbyPlaceFinderTest.java @@ -111,16 +111,16 @@ public void build() { street(C, D, 100, StreetTraversalPermission.ALL); tripPattern( - TP1 = TripPattern.of(FeedScopedIdForTestFactory.id("TP1")) + (TP1 = TripPattern.of(FeedScopedIdForTestFactory.id("TP1")) .withRoute(R1) .withStopPattern(new StopPattern(List.of(st(S1), st(S2)))) - .build() + .build()) ); tripPattern( - TP2 = TripPattern.of(FeedScopedIdForTestFactory.id("TP2")) + (TP2 = TripPattern.of(FeedScopedIdForTestFactory.id("TP2")) .withRoute(R2) .withStopPattern(new StopPattern(List.of(st(S1), st(S3)))) - .build() + .build()) ); } } diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestConstrainedBoardingSearch.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestConstrainedBoardingSearch.java index 97f6b5fd4af..3ed79ac4cab 100644 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestConstrainedBoardingSearch.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestConstrainedBoardingSearch.java @@ -21,7 +21,8 @@ */ @Deprecated public class TestConstrainedBoardingSearch - implements RaptorConstrainedBoardingSearch { + implements RaptorConstrainedBoardingSearch +{ /** Index of guaranteed transfers by fromStopPos */ private final TIntObjectMap> transfersByFromStopPos = diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransitData.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransitData.java index 6629cd4e77d..059ccd592fd 100644 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransitData.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransitData.java @@ -39,7 +39,8 @@ @Deprecated @SuppressWarnings("UnusedReturnValue") public class TestTransitData - implements RaptorTransitDataProvider, RaptorTestConstants { + implements RaptorTransitDataProvider, RaptorTestConstants +{ public static final TransferConstraint TX_GUARANTEED = TransferConstraint.of() .guaranteed() @@ -156,7 +157,8 @@ public RaptorStopNameResolver stopNameResolver() { @Override public int getValidTransitDataStartTime() { - return this.routes.stream() + return this.routes + .stream() .mapToInt(route -> route.timetable().getTripSchedule(0).departure(0)) .min() .orElseThrow(); @@ -164,7 +166,8 @@ public int getValidTransitDataStartTime() { @Override public int getValidTransitDataEndTime() { - return this.routes.stream() + return this.routes + .stream() .mapToInt(route -> { RaptorTimeTable timetable = route.timetable(); RaptorTripPattern pattern = route.pattern(); diff --git a/application/src/test/java/org/opentripplanner/routing/alertpatch/AlertCalendarTest.java b/application/src/test/java/org/opentripplanner/routing/alertpatch/AlertCalendarTest.java index 7636e69e50d..adc0f878d7d 100644 --- a/application/src/test/java/org/opentripplanner/routing/alertpatch/AlertCalendarTest.java +++ b/application/src/test/java/org/opentripplanner/routing/alertpatch/AlertCalendarTest.java @@ -1,9 +1,9 @@ package org.opentripplanner.routing.alertpatch; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.time.Instant; import java.util.List; @@ -18,25 +18,14 @@ class AlertCalendarTest { private static final Instant LATER_END = Instant.parse("2024-01-02T12:00:00Z"); @Test - void neverActive() { - var subject = AlertCalendar.ofNeverActive(); - assertTrue(subject.isNeverActive()); - assertThat(subject.timePeriods()).isEmpty(); - assertFalse(subject.isActiveDuring(TimePeriod.of(START, END))); - assertThat(subject.effectiveStart()).isEmpty(); - assertThat(subject.effectiveEnd()).isEmpty(); - } - - @Test - void ofEmptyCollectionIsNeverActive() { - assertEquals(AlertCalendar.ofNeverActive(), AlertCalendar.of(List.of())); + void ofEmptyCollectionIsRejected() { + assertThrows(IllegalArgumentException.class, () -> AlertCalendar.of(List.of())); } @Test void ofAlwaysActive() { var subject = AlertCalendar.ofAlwaysActive(); assertThat(subject.timePeriods()).containsExactly(TimePeriod.ofUnbounded()); - assertFalse(subject.isNeverActive()); assertTrue(subject.isActiveDuring(TimePeriod.of(START, END))); assertThat(subject.effectiveStart()).isEmpty(); assertThat(subject.effectiveEnd()).isEmpty(); @@ -52,7 +41,7 @@ void effectiveBounds() { } @Test - void openStartGivesNoEffectiveStart() { + void unboundedStartGivesNoEffectiveStart() { var subject = AlertCalendar.of( List.of(TimePeriod.of(null, END), TimePeriod.of(LATER_START, LATER_END)) ); @@ -61,7 +50,7 @@ void openStartGivesNoEffectiveStart() { } @Test - void openEndGivesNoEffectiveEnd() { + void unboundedEndGivesNoEffectiveEnd() { var subject = AlertCalendar.of( List.of(TimePeriod.of(START, END), TimePeriod.of(LATER_START, null)) ); diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/FilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/FilterTest.java index 0e206654cfd..aa711f3a5c1 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/FilterTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/FilterTest.java @@ -97,7 +97,11 @@ public void testOne() { ); var filterRequest = TransitFilterRequest.of() - .addSelect(SelectRequest.of().withRoutes(List.of(id(ROUTE_ID_1))).build()) + .addSelect( + SelectRequest.of() + .withRoutes(List.of(id(ROUTE_ID_1))) + .build() + ) .build(); Collection bannedPatterns = bannedPatterns(List.of(filterRequest), patterns); @@ -139,7 +143,11 @@ public void testTwo() { ); var filterRequest = TransitFilterRequest.of() - .addNot(SelectRequest.of().withAgencies(List.of(id(AGENCY_ID_1))).build()) + .addNot( + SelectRequest.of() + .withAgencies(List.of(id(AGENCY_ID_1))) + .build() + ) .build(); Collection bannedPatterns = bannedPatterns(List.of(filterRequest), patterns); @@ -246,11 +254,19 @@ public void testFour() { ); var filter1 = TransitFilterRequest.of() - .addSelect(SelectRequest.of().withRoutes(List.of(id(ROUTE_ID_1))).build()) + .addSelect( + SelectRequest.of() + .withRoutes(List.of(id(ROUTE_ID_1))) + .build() + ) .build(); var filter2 = TransitFilterRequest.of() - .addSelect(SelectRequest.of().withRoutes(List.of(id(ROUTE_ID_2))).build()) + .addSelect( + SelectRequest.of() + .withRoutes(List.of(id(ROUTE_ID_2))) + .build() + ) .build(); Collection bannedPatterns = bannedPatterns(List.of(filter1, filter2), patterns); @@ -290,11 +306,19 @@ public void testFive() { ); var filter1 = TransitFilterRequest.of() - .addSelect(SelectRequest.of().withRoutes(List.of(id(ROUTE_ID_1))).build()) + .addSelect( + SelectRequest.of() + .withRoutes(List.of(id(ROUTE_ID_1))) + .build() + ) .build(); var filter2 = TransitFilterRequest.of() - .addNot(SelectRequest.of().withRoutes(List.of(id(ROUTE_ID_1))).build()) + .addNot( + SelectRequest.of() + .withRoutes(List.of(id(ROUTE_ID_1))) + .build() + ) .build(); Collection bannedPatterns = bannedPatterns(List.of(filter1, filter2), patterns); @@ -335,8 +359,16 @@ public void testSix() { ); var filterRequest = TransitFilterRequest.of() - .addSelect(SelectRequest.of().withAgencies(List.of(id(AGENCY_ID_1))).build()) - .addNot(SelectRequest.of().withRoutes(List.of(id(ROUTE_ID_3))).build()) + .addSelect( + SelectRequest.of() + .withAgencies(List.of(id(AGENCY_ID_1))) + .build() + ) + .addNot( + SelectRequest.of() + .withRoutes(List.of(id(ROUTE_ID_3))) + .build() + ) .build(); Collection bannedPatterns = bannedPatterns(List.of(filterRequest), patterns); @@ -381,12 +413,24 @@ public void testSeven() { ); var filter1 = TransitFilterRequest.of() - .addSelect(SelectRequest.of().withAgencies(List.of(id(AGENCY_ID_1))).build()) + .addSelect( + SelectRequest.of() + .withAgencies(List.of(id(AGENCY_ID_1))) + .build() + ) .build(); var filter2 = TransitFilterRequest.of() - .addSelect(SelectRequest.of().withAgencies(List.of(id(AGENCY_ID_2))).build()) - .addNot(SelectRequest.of().withRoutes(List.of(id(ROUTE_ID_3))).build()) + .addSelect( + SelectRequest.of() + .withAgencies(List.of(id(AGENCY_ID_2))) + .build() + ) + .addNot( + SelectRequest.of() + .withRoutes(List.of(id(ROUTE_ID_3))) + .build() + ) .build(); Collection bannedPatterns = bannedPatterns(List.of(filter1, filter2), patterns); @@ -506,7 +550,11 @@ public void testNine() { .withTransportModes(List.of(new MainAndSubMode(TransitMode.BUS))) .build() ) - .addNot(SelectRequest.of().withRoutes(List.of(id(ROUTE_ID_3))).build()) + .addNot( + SelectRequest.of() + .withRoutes(List.of(id(ROUTE_ID_3))) + .build() + ) .build(); Collection bannedPatterns = bannedPatterns(List.of(filter), patterns); @@ -563,7 +611,11 @@ public void testTen() { ); var filter = TransitFilterRequest.of() - .addSelect(SelectRequest.of().withAgencies(List.of(id(AGENCY_ID_1))).build()) + .addSelect( + SelectRequest.of() + .withAgencies(List.of(id(AGENCY_ID_1))) + .build() + ) .addNot( SelectRequest.of() .withTransportModes(List.of(new MainAndSubMode(TransitMode.BUS))) diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/TestBanning.java b/application/src/test/java/org/opentripplanner/routing/algorithm/TestBanning.java index 9faada50da7..8dfbf23f8d0 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/TestBanning.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/TestBanning.java @@ -27,8 +27,16 @@ public void testSetBannedOnRequest() { Collection patterns = getTestPatterns(); var filterRequest = TransitFilterRequest.of() - .addNot(SelectRequest.of().withRoutes(List.of(id("RUT:Route:1"))).build()) - .addNot(SelectRequest.of().withAgencies(List.of(id("RUT:Agency:2"))).build()) + .addNot( + SelectRequest.of() + .withRoutes(List.of(id("RUT:Route:1"))) + .build() + ) + .addNot( + SelectRequest.of() + .withAgencies(List.of(id("RUT:Agency:2"))) + .build() + ) .build(); Collection bannedPatterns = bannedPatterns(List.of(filterRequest), patterns); @@ -43,8 +51,16 @@ public void testSetWhiteListedOnRequest() { Collection patterns = getTestPatterns(); var filterRequest = TransitFilterRequest.of() - .addSelect(SelectRequest.of().withRoutes(List.of(id("RUT:Route:1"))).build()) - .addSelect(SelectRequest.of().withAgencies(List.of(id("RUT:Agency:2"))).build()) + .addSelect( + SelectRequest.of() + .withRoutes(List.of(id("RUT:Route:1"))) + .build() + ) + .addSelect( + SelectRequest.of() + .withAgencies(List.of(id("RUT:Agency:2"))) + .build() + ) .build(); Collection bannedPatterns = bannedPatterns(List.of(filterRequest), patterns); diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java index 0e89a76e0c7..8d8a6eff453 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java @@ -75,7 +75,9 @@ void setUpItineraries() { i2 = newItinerary(A).bus(21, T11_06, T11_09, E).build(); // Not optimal, departure is very late - i3 = newItinerary(A).bus(20, I3_LATE_START_TIME, I3_LATE_START_TIME + D1_m, E).build(); + i3 = newItinerary(A) + .bus(20, I3_LATE_START_TIME, I3_LATE_START_TIME + D1_m, E) + .build(); } @Test @@ -279,7 +281,9 @@ void departuresOnDifferentServiceDatesShouldNotBeGroupedTogether() { // group these and flag any of them for deletion, because the 24h difference means they are // different TripOnServiceDate. This situation commonly arises with multi-day ferry routes, // such as the ones along the Norwegian cost. - var day1 = newItinerary(A).bus(TRIP_ID, T11_00, T11_00 + D50_h, B, date1).build(COST); + var day1 = newItinerary(A) + .bus(TRIP_ID, T11_00, T11_00 + D50_h, B, date1) + .build(COST); var day2 = newItinerary(A) .bus(TRIP_ID, T11_00 + D24_h, T11_00 + D24_h + D50_h, B, date2) .build(COST); diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/McMaxLimitFilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/McMaxLimitFilterTest.java index 7f7e5df01d1..1fb7c0d435c 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/McMaxLimitFilterTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/McMaxLimitFilterTest.java @@ -72,9 +72,7 @@ static TestRow row( static List> filterTestCases() { return List.of( - List.of( - /* Should not fail for an empty list of itineraries*/ - ), + List.of(/* Should not fail for an empty list of itineraries*/), List.of( // Test minNumItinerariesLimit = 2 row(EXP_KEEP, COST_LOW, TX_1, GROUP_A, "Best in everything"), diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandlerTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandlerTest.java index 2fc4b3943e8..61a4c80d294 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandlerTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandlerTest.java @@ -128,7 +128,9 @@ static class TestCase { this.numItineraries = numItineraries; this.i1 = newItinerary(A, T11_06).walk(D2_m, E).build(); this.i2 = newItinerary(A).bus(21, T11_06, T11_09, E).build(); - this.i3 = newItinerary(A).bus(20, T11_33, T11_33 + D1_m, E).build(); + this.i3 = newItinerary(A) + .bus(20, T11_33, T11_33 + D1_m, E) + .build(); addSystemNotice(i2, i2Tag); addSystemNotice(i3, i3Tag); this.expected = expected(List.of(i1, i2, i3), expected); @@ -151,7 +153,7 @@ private static List expected(List all, List index @Override public String toString() { // Include test input, not expected - return ("n:" + numItineraries + " tags: na " + tag(i2) + " " + tag(i3)); + return "n:" + numItineraries + " tags: na " + tag(i2) + " " + tag(i3); } private static void addSystemNotice(Itinerary it, String tag) { diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/LegsToItineraryMapperTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/LegsToItineraryMapperTest.java index e9eafe2ee03..2b5984d997d 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/LegsToItineraryMapperTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/LegsToItineraryMapperTest.java @@ -10,7 +10,6 @@ import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.service.streetdetails.internal.DefaultStreetDetailsRepository; import org.opentripplanner.service.streetdetails.internal.DefaultStreetDetailsService; -import org.opentripplanner.street.internal.notes.StreetNotesService; import org.opentripplanner.street.model.path.StreetPath; import org.opentripplanner.street.search.state.State; import org.opentripplanner.street.search.state.TestStateBuilder; @@ -38,7 +37,6 @@ void isSearchWindowAware(State state) { var mapper = new StreetPathToLegsMapper( new NoopSiteResolver(), ZoneIds.UTC, - new StreetNotesService(), new DefaultStreetDetailsService(new DefaultStreetDetailsRepository()), 1 ); diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java index 8a12b2ec48c..6cad5d6115a 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java @@ -42,17 +42,19 @@ import org.opentripplanner.model.plan.leg.StreetLeg; import org.opentripplanner.routing.algorithm.mapping._support.mapping.ItineraryMapper; import org.opentripplanner.routing.algorithm.mapping._support.model.ApiLeg; +import org.opentripplanner.routing.api.RoutingService; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.RouteRequestBuilder; import org.opentripplanner.routing.api.request.request.filter.AllowAllTransitFilter; import org.opentripplanner.routing.api.request.request.filter.TransitFilterRequest; import org.opentripplanner.routing.api.response.RoutingResponse; -import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.standalone.api.TestServerContext; +import org.opentripplanner.standalone.config.RouterConfig; import org.opentripplanner.street.model.StreetMode; import org.opentripplanner.transit.model.basic.MainAndSubMode; import org.opentripplanner.transit.model.basic.NarrowedTransitMode; import org.opentripplanner.transit.model.basic.TransitMode; +import org.opentripplanner.transit.service.TransitService; import org.opentripplanner.utils.time.DurationUtils; /** @@ -74,7 +76,8 @@ public abstract class SnapshotTestBase { static final boolean VERBOSE = Boolean.getBoolean("otp.test.verbose"); - protected OtpServerRequestContext serverContext; + protected TransitService transitService; + protected RoutingService routingService; public static void loadGraphBeforeClass(boolean withElevation) { if (withElevation) { @@ -84,20 +87,19 @@ public static void loadGraphBeforeClass(boolean withElevation) { } } - protected OtpServerRequestContext serverContext() { - if (serverContext == null) { + private void ensureContextInitialized() { + if (routingService == null) { TestOtpModel model = getGraph(); - serverContext = TestServerContext.createServerContext( - model.graph(), + transitService = TestServerContext.createTransitService( model.transitRepository(), - model.transferRepository(), - model.fareServiceFactory().makeFareService(), - null, - null + model.transferRepository() + ); + routingService = TestServerContext.createRoutingService( + model.graph(), + transitService, + model.transferRepository() ); } - - return serverContext; } protected TestOtpModel getGraph() { @@ -112,14 +114,13 @@ protected RouteRequestBuilder createTestRequest( int minute, int second ) { - OtpServerRequestContext serverContext = serverContext(); + ensureContextInitialized(); - var builder = serverContext - .defaultRouteRequest() + var builder = RouterConfig.DEFAULT.routingRequestDefaults() .copyOf() .withDateTime( LocalDateTime.of(year, month, day, hour, minute, second) - .atZone(ZoneId.of(serverContext.transitService().getTimeZone().getId())) + .atZone(ZoneId.of(transitService.getTimeZone().getId())) .toInstant() ) .withPreferences(pref -> pref.withTransfer(tx -> tx.withMaxTransfers(6))) @@ -152,9 +153,7 @@ protected void printItineraries( for (int j = 0; j < itinerary.legs().size(); j++) { Leg leg = itinerary.legs().get(j); - String mode = (leg instanceof StreetLeg stLeg) - ? stLeg.getMode().name().substring(0, 1) - : "T"; + String mode = leg instanceof StreetLeg stLeg ? stLeg.getMode().name().substring(0, 1) : "T"; System.out.printf( " - leg %2d - %52.52s %9s --%s-> %-9s %-52.52s\n", j, @@ -232,8 +231,9 @@ private static String asJsonString(Object object) { } private List retrieveItineraries(RouteRequest request) { + ensureContextInitialized(); long startMillis = System.currentTimeMillis(); - RoutingResponse response = serverContext.routingService().route(request); + RoutingResponse response = routingService.route(request); List itineraries = response.getTripPlan().itineraries; @@ -242,15 +242,16 @@ private List retrieveItineraries(RouteRequest request) { itineraries, startMillis, System.currentTimeMillis(), - serverContext.transitService().getTimeZone() + transitService.getTimeZone() ); } return itineraries; } private String createDebugUrlForRequest(RouteRequest request) { + ensureContextInitialized(); var dateTime = Instant.ofEpochSecond(request.dateTime().getEpochSecond()) - .atZone(serverContext().transitService().getTimeZone()) + .atZone(transitService.getTimeZone()) .toLocalDateTime(); // TODO: 2022-12-20 filters: there should not be more than one filter but technically this is not right diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapperTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapperTest.java index bc8372bf17d..0053ada394a 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapperTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapperTest.java @@ -25,7 +25,6 @@ import org.opentripplanner.service.streetdetails.internal.DefaultStreetDetailsRepository; import org.opentripplanner.service.streetdetails.internal.DefaultStreetDetailsService; import org.opentripplanner.street.geometry.WgsCoordinate; -import org.opentripplanner.street.internal.notes.StreetNotesService; import org.opentripplanner.street.search.state.TestStateBuilder; import org.opentripplanner.transit.model.site.Entrance; @@ -161,7 +160,6 @@ private static List buildWalkSteps(TestStateBuilder builder) { var mapper = new StatesToWalkStepsMapper( path.states, null, - new StreetNotesService(), new DefaultStreetDetailsService(new DefaultStreetDetailsRepository()), id -> Entrance.of(id).withCoordinate(WgsCoordinate.GREENWICH).build(), 0 diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/StreetPathToLegsMapperTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/StreetPathToLegsMapperTest.java index dc2074cface..dda96756d77 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/StreetPathToLegsMapperTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/StreetPathToLegsMapperTest.java @@ -9,7 +9,6 @@ import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.service.streetdetails.internal.DefaultStreetDetailsRepository; import org.opentripplanner.service.streetdetails.internal.DefaultStreetDetailsService; -import org.opentripplanner.street.internal.notes.StreetNotesService; import org.opentripplanner.street.model.path.StreetPath; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.street.search.state.TestStateBuilder; @@ -38,7 +37,6 @@ private StreetPathToLegsMapper mapper() { return new StreetPathToLegsMapper( new NoopSiteResolver(), ZoneIds.UTC, - new StreetNotesService(), new DefaultStreetDetailsService(new DefaultStreetDetailsRepository()), 1 ); diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/TripPlanMapperTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/TripPlanMapperTest.java index e208a7eb32e..86c26d8eba9 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/TripPlanMapperTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/TripPlanMapperTest.java @@ -30,8 +30,8 @@ void mapRequestWithNoItineraries() { assertNotNull(tripPlan); assertEquals(DATETIME, tripPlan.date); - assertEquals(new WgsCoordinate(FROM.getCoordinate()), (tripPlan.from.coordinate)); - assertEquals(new WgsCoordinate(TO.getCoordinate()), (tripPlan.to.coordinate)); + assertEquals(new WgsCoordinate(FROM.getCoordinate()), tripPlan.from.coordinate); + assertEquals(new WgsCoordinate(TO.getCoordinate()), tripPlan.to.coordinate); assertTrue(tripPlan.itineraries.isEmpty()); } } diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/_support/mapping/LegMapper.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/_support/mapping/LegMapper.java index 3d2420942bb..db8279a2d2c 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/_support/mapping/LegMapper.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/_support/mapping/LegMapper.java @@ -42,8 +42,8 @@ public List mapLegs(List domain) { final int lastIdx = size - 1; for (int i = 0; i < size; ++i) { - ZonedDateTime arrivalTimeFromPlace = (i == 0) ? null : domain.get(i - 1).endTime(); - ZonedDateTime departureTimeToPlace = (i == lastIdx) ? null : domain.get(i + 1).startTime(); + ZonedDateTime arrivalTimeFromPlace = i == 0 ? null : domain.get(i - 1).endTime(); + ZonedDateTime departureTimeToPlace = i == lastIdx ? null : domain.get(i + 1).startTime(); apiLegs.add(mapLeg(domain.get(i), arrivalTimeFromPlace, departureTimeToPlace)); } diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/_support/mapping/PlaceMapper.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/_support/mapping/PlaceMapper.java index b05f2233cfa..c3496427f75 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/_support/mapping/PlaceMapper.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/_support/mapping/PlaceMapper.java @@ -65,12 +65,12 @@ public ApiPlace mapPlace( if (domain.stop != null) { api.stopId = FeedScopedIdMapper.mapToApi(domain.stop.getId()); api.stopCode = domain.stop.getCode(); - api.platformCode = domain.stop instanceof RegularStop - ? ((RegularStop) domain.stop).getPlatformCode() - : null; - api.zoneId = domain.stop instanceof RegularStop - ? ((RegularStop) domain.stop).getFirstZoneAsString() - : null; + api.platformCode = + domain.stop instanceof RegularStop ? ((RegularStop) domain.stop).getPlatformCode() : null; + api.zoneId = + domain.stop instanceof RegularStop + ? ((RegularStop) domain.stop).getFirstZoneAsString() + : null; } if (domain.coordinate != null) { diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorTransitDataMapperTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorTransitDataMapperTest.java index cd1c189f3e4..c5e304821bc 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorTransitDataMapperTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorTransitDataMapperTest.java @@ -35,10 +35,22 @@ class RaptorTransitDataMapperTest { .build(); private final RegularStop STOP_0 = testModel.stop("ID-" + 1).build(); - private final RegularStop STOP_1 = testModel.stop("ID-" + 2).withParentStation(STATION_A).build(); - private final RegularStop STOP_2 = testModel.stop("ID-" + 3).withParentStation(STATION_B).build(); - private final RegularStop STOP_3 = testModel.stop("ID-" + 4).withParentStation(STATION_C).build(); - private final RegularStop STOP_4 = testModel.stop("ID-" + 5).withParentStation(STATION_D).build(); + private final RegularStop STOP_1 = testModel + .stop("ID-" + 2) + .withParentStation(STATION_A) + .build(); + private final RegularStop STOP_2 = testModel + .stop("ID-" + 3) + .withParentStation(STATION_B) + .build(); + private final RegularStop STOP_3 = testModel + .stop("ID-" + 4) + .withParentStation(STATION_C) + .build(); + private final RegularStop STOP_4 = testModel + .stop("ID-" + 5) + .withParentStation(STATION_D) + .build(); private final List STOPS = Arrays.asList(STOP_0, STOP_1, STOP_2, STOP_3, STOP_4); @Test diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearchTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearchTest.java index b6905c7514a..cce3942f8a7 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearchTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearchTest.java @@ -161,7 +161,9 @@ public void alightFirstAvailableTripForABigNumberOfTrips() { .withIndex(i); // Search and find trip 'i' using the previous trip index - searchForTrip(tripAlightTime, STOP_POS_0, i - 1).assertTripFound().withIndex(i); + searchForTrip(tripAlightTime, STOP_POS_0, i - 1) + .assertTripFound() + .withIndex(i); // Search with a time and index that together exclude trip 'i' searchForTrip(tripAlightTime, STOP_POS_0, i).assertNoTripFound(); diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearchTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearchTest.java index 288c22e1ce0..a5d2bb64c85 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearchTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearchTest.java @@ -94,12 +94,16 @@ public void boardFirstTripWithTheMinimumPossibleSlack() { searchForTrip(TIME_A1, STOP_POS_0).assertTripFound().withIndex(TRIP_A).withBoardTime(TIME_A1); // Assert board next trip for: time + 1 second - searchForTrip(TIME_A1 + 1, STOP_POS_0).assertTripFound().withIndex(TRIP_B); + searchForTrip(TIME_A1 + 1, STOP_POS_0) + .assertTripFound() + .withIndex(TRIP_B); searchForTrip(TIME_A2, STOP_POS_1).assertTripFound().withIndex(TRIP_A).withBoardTime(TIME_A2); // Assert board next trip for: time + 1 second - searchForTrip(TIME_A2 + 1, STOP_POS_1).assertTripFound().withIndex(TRIP_B); + searchForTrip(TIME_A2 + 1, STOP_POS_1) + .assertTripFound() + .withIndex(TRIP_B); } @Test @@ -158,7 +162,9 @@ public void boardFirstAvailableTripForABigNumberOfTrips() { .withBoardTime(tripBoardTime); // Search and find trip 'i' using the next trip index - searchForTrip(tripBoardTime, STOP_POS_0, i + 1).assertTripFound().withIndex(i); + searchForTrip(tripBoardTime, STOP_POS_0, i + 1) + .assertTripFound() + .withIndex(i); // Search with a time and index that together exclude trip 'i' searchForTrip(tripBoardTime, STOP_POS_0, i).assertNoTripFound(); diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughOneTransferTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughOneTransferTest.java index 11a75ce6cb4..89f866eb21c 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughOneTransferTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughOneTransferTest.java @@ -65,7 +65,9 @@ static List tripWithOneTransferTestCases() { testCase().points(STOP_H).expectTransfer(STOP_C, STOP_G), testCase().points(STOP_I).expectTransfer(STOP_C, STOP_H), // Two stops in one pass-through point - testCase().points(STOP_B, STOP_C).expectTransfer(STOP_D, STOP_H), + testCase() + .points(STOP_B, STOP_C) + .expectTransfer(STOP_D, STOP_H), testCase().points(STOP_B, STOP_D).expectTransfer(STOP_C, STOP_H), testCase().points(STOP_B, STOP_G).expectTransfer(STOP_C, STOP_H), testCase().points(STOP_B, STOP_H).expectTransfer(STOP_C, STOP_G), @@ -81,7 +83,10 @@ static List tripWithOneTransferTestCases() { testCase().points(STOP_G, STOP_I).expectTransfer(STOP_C, STOP_H), testCase().points(STOP_H, STOP_I).expectTransfer(STOP_C, STOP_G), // Two stops in two pass-through points - testCase().points(STOP_B).points(STOP_C).expectTransfer(STOP_D, STOP_H), + testCase() + .points(STOP_B) + .points(STOP_C) + .expectTransfer(STOP_D, STOP_H), testCase().points(STOP_B).points(STOP_D).expectTransfer(STOP_D, STOP_H), testCase().points(STOP_B).points(STOP_G).expectTransfer(STOP_C, STOP_G), testCase().points(STOP_B).points(STOP_H).expectTransfer(STOP_C, STOP_G), @@ -126,16 +131,17 @@ static List tripWithOneTransferTestCases() { @ParameterizedTest @MethodSource("tripWithOneTransferTestCases") public void tripWithOneTransfer(TestCase tc) { - var txCost = new WalkDurationForStopCombinations(N_STOPS) - .withPassThroughPoints(tc.points(), 10) - // This transfer do not visit D - .addTxCost(STOP_C, STOP_G, 2) - // This transfer do not visit D and G; hence given the lowest cost - .addTxCost(STOP_C, STOP_H, 1) - // This transfer visit all stops; Hence given the highest cost - .addTxCost(STOP_D, STOP_G, 3) - // This transfer do not visit G - .addTxCost(STOP_D, STOP_H, 2); + var txCost = + new WalkDurationForStopCombinations(N_STOPS) + .withPassThroughPoints(tc.points(), 10) + // This transfer do not visit D + .addTxCost(STOP_C, STOP_G, 2) + // This transfer do not visit D and G; hence given the lowest cost + .addTxCost(STOP_C, STOP_H, 1) + // This transfer visit all stops; Hence given the highest cost + .addTxCost(STOP_D, STOP_G, 3) + // This transfer do not visit G + .addTxCost(STOP_D, STOP_H, 2); // We need *a* path - the transfer here can be any. var originalPath = pathBuilder() diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughTwoTransfersTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughTwoTransfersTest.java index 925a5f05770..d8cdcf75145 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughTwoTransfersTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughTwoTransfersTest.java @@ -59,7 +59,9 @@ static List tripWithTwoTransferTestCases() { // None pass-through-points testCase("").expectTransfersFrom(STOP_C, STOP_H), // One pass-through-points - testCase().points(STOP_B).expectTransfersFrom(STOP_C, STOP_H), + testCase() + .points(STOP_B) + .expectTransfersFrom(STOP_C, STOP_H), testCase().points(STOP_C).expectTransfersFrom(STOP_C, STOP_H), testCase().points(STOP_D).expectTransfersFrom(STOP_E, STOP_J), testCase().points(STOP_E).expectTransfersFrom(STOP_E, STOP_J), @@ -91,7 +93,10 @@ static List tripWithTwoTransferTestCases() { testCase("at J w/unreachable F").points(STOP_J, STOP_F).expectTransfersFrom(STOP_C, STOP_J), testCase("at L w/unreachable F").points(STOP_L, STOP_F).expectTransfersFrom(STOP_C, STOP_H), // Two pass-through-points - a few samples - testCase().points(STOP_B).points(STOP_C).expectTransfersFrom(STOP_C, STOP_H), + testCase() + .points(STOP_B) + .points(STOP_C) + .expectTransfersFrom(STOP_C, STOP_H), testCase().points(STOP_B).points(STOP_D).expectTransfersFrom(STOP_E, STOP_J), testCase().points(STOP_B).points(STOP_E).expectTransfersFrom(STOP_E, STOP_J), testCase().points(STOP_B).points(STOP_G).expectTransfersFrom(STOP_C, STOP_H), diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestCase.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestCase.java index 5ead19d2739..b580b67231e 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestCase.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestCase.java @@ -55,14 +55,12 @@ public String toString() { .append(fromAToB ? " to " : " and ") .append(stopIndexToName(stopIndexB)); } - buf - .append(". ") - .append( - points - .stream() - .map(p -> p.toString(this::stopIndexToName)) - .toList() - ); + buf.append(". ").append( + points + .stream() + .map(p -> p.toString(this::stopIndexToName)) + .toList() + ); return buf.toString(); } diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestUtils.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestUtils.java index 9cc5a967dd6..83b5e8a69a4 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestUtils.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestUtils.java @@ -65,7 +65,7 @@ static OptimizePathDomainService domainService( null, 0.0, filter, - (new RaptorTestConstants() {})::stopIndexToName + new RaptorTestConstants() {}::stopIndexToName ); } diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceTest.java index 32a2dafdf02..9a708ba6282 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceTest.java @@ -338,7 +338,7 @@ static OptimizePathDomainService subject( null, 0.0, filter, - (new RaptorTestConstants() {})::stopIndexToName + new RaptorTestConstants() {}::stopIndexToName ); } } diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TestTransferBuilder.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TestTransferBuilder.java index ccddf3288fc..5edf6bd8979 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TestTransferBuilder.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TestTransferBuilder.java @@ -140,9 +140,8 @@ public TripToTripTransfer build() { validateFromTo(); validateWalkDurationSec(); - var pathTransfer = fromStopIndex == toStopIndex - ? null - : TestTransfers.transfer(toStopIndex, walkDurationSec); + var pathTransfer = + fromStopIndex == toStopIndex ? null : TestTransfers.transfer(toStopIndex, walkDurationSec); return new TripToTripTransfer<>( arrival(fromTrip, fromStopIndex), diff --git a/application/src/test/java/org/opentripplanner/routing/api/request/request/JourneyRequestTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/request/JourneyRequestTest.java index f4f2b0917dd..32dd5acd6e0 100644 --- a/application/src/test/java/org/opentripplanner/routing/api/request/request/JourneyRequestTest.java +++ b/application/src/test/java/org/opentripplanner/routing/api/request/request/JourneyRequestTest.java @@ -15,7 +15,11 @@ class JourneyRequestTest { private static final TransitRequest TRANSIT = TransitRequest.of() .withFilter(b -> - b.addSelect(SelectRequest.of().withRoutes(List.of(new FeedScopedId("F", "R:1"))).build()) + b.addSelect( + SelectRequest.of() + .withRoutes(List.of(new FeedScopedId("F", "R:1"))) + .build() + ) ) .build(); private static final StreetRequest ACCESS = new StreetRequest(StreetMode.BIKE_TO_PARK); diff --git a/application/src/test/java/org/opentripplanner/routing/core/TurnsTest.java b/application/src/test/java/org/opentripplanner/routing/core/TurnsTest.java index b139dd1ff44..8d041b56d89 100644 --- a/application/src/test/java/org/opentripplanner/routing/core/TurnsTest.java +++ b/application/src/test/java/org/opentripplanner/routing/core/TurnsTest.java @@ -18,9 +18,10 @@ public class TurnsTest { public void testIntersectionVertex() { GeometryFactory gf = new GeometryFactory(); - LineString geometry = gf.createLineString( - new Coordinate[] { new Coordinate(-0.10, 0), new Coordinate(0, 0) } - ); + LineString geometry = gf.createLineString(new Coordinate[] { + new Coordinate(-0.10, 0), + new Coordinate(0, 0), + }); IntersectionVertex v1 = StreetModelForTest.intersectionVertex("v1", -0.10, 0); IntersectionVertex v2 = StreetModelForTest.intersectionVertex("v2", 0, 0); @@ -35,9 +36,10 @@ public void testIntersectionVertex() { .withBack(true) .buildAndConnect(); - LineString geometry2 = gf.createLineString( - new Coordinate[] { new Coordinate(0, 0), new Coordinate(-0.10, 0) } - ); + LineString geometry2 = gf.createLineString(new Coordinate[] { + new Coordinate(0, 0), + new Coordinate(-0.10, 0), + }); StreetEdge rightEdge = new StreetEdgeBuilder<>() .withFromVertex(v1) diff --git a/application/src/test/java/org/opentripplanner/routing/graph/GraphSerializationTest.java b/application/src/test/java/org/opentripplanner/routing/graph/GraphSerializationTest.java index df67e5467fd..409bc9eeab2 100644 --- a/application/src/test/java/org/opentripplanner/routing/graph/GraphSerializationTest.java +++ b/application/src/test/java/org/opentripplanner/routing/graph/GraphSerializationTest.java @@ -314,7 +314,9 @@ private static EmpiricalDelayRepository empiricalDelayRepository() { .build(); repository.addEmpiricalDelayServiceCalendar(FEED_ID, cal); repository.addTripDelays( - TripDelays.of(A_TRIP_ID).with("serviceId", List.of(new EmpiricalDelay(2, 19))).build() + TripDelays.of(A_TRIP_ID) + .with("serviceId", List.of(new EmpiricalDelay(2, 19))) + .build() ); return repository; } diff --git a/application/src/test/java/org/opentripplanner/routing/impl/TransitAlertServiceImplTest.java b/application/src/test/java/org/opentripplanner/routing/impl/TransitAlertServiceImplTest.java index 01334735354..49f817136bb 100644 --- a/application/src/test/java/org/opentripplanner/routing/impl/TransitAlertServiceImplTest.java +++ b/application/src/test/java/org/opentripplanner/routing/impl/TransitAlertServiceImplTest.java @@ -6,13 +6,13 @@ import java.util.List; import java.util.Set; import org.junit.jupiter.api.Test; -import org.opentripplanner.core.model.i18n.I18NString; import org.opentripplanner.core.model.id.FeedScopedId; +import org.opentripplanner.routing.alertpatch.AlertCause; import org.opentripplanner.routing.alertpatch.EntitySelector; import org.opentripplanner.routing.alertpatch.TransitAlert; -import org.opentripplanner.transit.model.site.Station; -import org.opentripplanner.transit.service.SiteRepository; -import org.opentripplanner.transit.service.TransitRepository; +import org.opentripplanner.transit.api.request.TransitAlertRequest; +import org.opentripplanner.transit.model.filter.selector.FilterRequest; +import org.opentripplanner.transit.model.filter.transit.TransitAlertSelectRequest; class TransitAlertServiceImplTest { @@ -26,14 +26,6 @@ class TransitAlertServiceImplTest { private static final String METRO_P1_ID = "9400ZZLUKSX1"; private static final String BUS_STOP_ID = "490001276S"; - private static final Station RAIL_STATION = Station.of(id(RAIL_STATION_ID)) - .withName(I18NString.of("London St Pancras")) - .withCoordinate(51.532719, -0.126997) - .build(); - private static final Station METRO_STATION = Station.of(id(METRO_STATION_ID)) - .withName(I18NString.of("King's Cross St. Pancras")) - .withCoordinate(51.5306090, -0.1239491) - .build(); private static final TransitAlert RAIL_STATION_ALERT = TransitAlert.of(id("rail_station_alert")) .addEntity(new EntitySelector.Stop(id(RAIL_STATION_ID))) @@ -44,24 +36,14 @@ class TransitAlertServiceImplTest { private static final TransitAlert BUS_STOP_ALERT = TransitAlert.of(id("bus_stop_alert")) .addEntity(new EntitySelector.Stop(id(BUS_STOP_ID))) .build(); - - private static final TransitRepository TIMETABLE_REPOSITORY = new TransitRepository( - getSiteRepository() - ); - - private static SiteRepository getSiteRepository() { - var builder = SiteRepository.of().withStations(List.of(RAIL_STATION, METRO_STATION)); - return builder - .withRegularStops( - List.of( - builder.regularStop(id(RAIL_P1_ID)).withParentStation(RAIL_STATION).build(), - builder.regularStop(id(RAIL_PA_ID)).withParentStation(RAIL_STATION).build(), - builder.regularStop(id(METRO_P1_ID)).withParentStation(METRO_STATION).build(), - builder.regularStop(id(BUS_STOP_ID)).withCoordinate(51.5314719, -0.1272119).build() - ) - ) - .build(); - } + private static final TransitAlert ACCIDENT_ALERT = TransitAlert.of(id("accident_alert")) + .addEntity(new EntitySelector.Stop(id(RAIL_P1_ID))) + .withCause(AlertCause.ACCIDENT) + .build(); + private static final TransitAlert WEATHER_ALERT = TransitAlert.of(id("weather_alert")) + .addEntity(new EntitySelector.Stop(id(BUS_STOP_ID))) + .withCause(AlertCause.WEATHER) + .build(); @Test void getStopAlerts() { @@ -142,6 +124,72 @@ private static TransitAlertServiceImpl serviceWithStopAlerts() { return service; } + @Test + void findAlertsWithoutFiltersReturnsAll() { + var iut = new TransitAlertServiceImpl(); + iut.setAlerts(List.of(ACCIDENT_ALERT, WEATHER_ALERT)); + + assertThat(iut.findAlerts(TransitAlertRequest.of().build())).containsExactly( + ACCIDENT_ALERT, + WEATHER_ALERT + ); + } + + @Test + void findAlertsSelectsMatchingCause() { + var iut = new TransitAlertServiceImpl(); + iut.setAlerts(List.of(ACCIDENT_ALERT, WEATHER_ALERT)); + + var request = request( + FilterRequest.of().addSelect(causeSelector(AlertCause.ACCIDENT)) + ); + + assertThat(iut.findAlerts(request)).containsExactly(ACCIDENT_ALERT); + } + + @Test + void findAlertsExcludesMatchingCause() { + var iut = new TransitAlertServiceImpl(); + iut.setAlerts(List.of(ACCIDENT_ALERT, WEATHER_ALERT)); + + var request = request( + FilterRequest.of().addNot(causeSelector(AlertCause.ACCIDENT)) + ); + + assertThat(iut.findAlerts(request)).containsExactly(WEATHER_ALERT); + } + + @Test + void findAlertsCombinesFiltersWithOr() { + var iut = new TransitAlertServiceImpl(); + iut.setAlerts(List.of(ACCIDENT_ALERT, WEATHER_ALERT)); + + var request = TransitAlertRequest.of() + .withFilters( + List.of( + FilterRequest.of() + .addSelect(causeSelector(AlertCause.ACCIDENT)) + .build(), + FilterRequest.of() + .addSelect(causeSelector(AlertCause.WEATHER)) + .build() + ) + ) + .build(); + + assertThat(iut.findAlerts(request)).containsExactly(ACCIDENT_ALERT, WEATHER_ALERT); + } + + private static TransitAlertRequest request( + FilterRequest.Builder filter + ) { + return TransitAlertRequest.of().withFilters(List.of(filter.build())).build(); + } + + private static TransitAlertSelectRequest causeSelector(AlertCause cause) { + return TransitAlertSelectRequest.of().withCauses(List.of(cause)).build(); + } + private static FeedScopedId id(String id) { return new FeedScopedId(FEED_ID, id); } diff --git a/application/src/test/java/org/opentripplanner/routing/linking/LinkingContextFactoryTest.java b/application/src/test/java/org/opentripplanner/routing/linking/LinkingContextFactoryTest.java index b9f15bd8fe7..51d34090d48 100644 --- a/application/src/test/java/org/opentripplanner/routing/linking/LinkingContextFactoryTest.java +++ b/application/src/test/java/org/opentripplanner/routing/linking/LinkingContextFactoryTest.java @@ -528,26 +528,22 @@ private GenericLocation stopToLocation(RegularStop s) { } private boolean outgoingEdgeIsTraversableWith(Collection edges, TraverseMode mode) { - return edges - .stream() - .anyMatch(outgoing -> - outgoing - .getToVertex() - .getOutgoingStreetEdges() - .stream() - .anyMatch(edge -> edge.canTraverse(mode)) - ); + return edges.stream().anyMatch(outgoing -> + outgoing + .getToVertex() + .getOutgoingStreetEdges() + .stream() + .anyMatch(edge -> edge.canTraverse(mode)) + ); } private boolean incomingEdgeIsTraversableWith(Collection edges, TraverseMode mode) { - return edges - .stream() - .anyMatch(incoming -> - incoming - .getFromVertex() - .getIncomingStreetEdges() - .stream() - .anyMatch(edge -> edge.canTraverse(mode)) - ); + return edges.stream().anyMatch(incoming -> + incoming + .getFromVertex() + .getIncomingStreetEdges() + .stream() + .anyMatch(edge -> edge.canTraverse(mode)) + ); } } diff --git a/application/src/test/java/org/opentripplanner/smoketest/SeattleSmokeTest.java b/application/src/test/java/org/opentripplanner/smoketest/SeattleSmokeTest.java index 48c4d87269f..ced30aba098 100644 --- a/application/src/test/java/org/opentripplanner/smoketest/SeattleSmokeTest.java +++ b/application/src/test/java/org/opentripplanner/smoketest/SeattleSmokeTest.java @@ -88,12 +88,10 @@ private TripPlan testAccessibleRouting(double walkReluctance) throws IOException var tripPlan = SmokeTest.API_CLIENT.plan(req); // assert that accessibility score is there - tripPlan - .itineraries() - .forEach(i -> { - assertTrue(i.accessibilityScore().isPresent()); - i.legs().forEach(l -> assertTrue(l.accessibilityScore().isPresent())); - }); + tripPlan.itineraries().forEach(i -> { + assertTrue(i.accessibilityScore().isPresent()); + i.legs().forEach(l -> assertTrue(l.accessibilityScore().isPresent())); + }); return tripPlan; } } diff --git a/application/src/test/java/org/opentripplanner/smoketest/util/RequestCombinationsBuilder.java b/application/src/test/java/org/opentripplanner/smoketest/util/RequestCombinationsBuilder.java index 485e3a8531e..9c81734a09c 100644 --- a/application/src/test/java/org/opentripplanner/smoketest/util/RequestCombinationsBuilder.java +++ b/application/src/test/java/org/opentripplanner/smoketest/util/RequestCombinationsBuilder.java @@ -79,14 +79,12 @@ private Stream duplicateIf( } private static Stream combineLocations(List places) { - return places - .stream() - .flatMap(place -> { - var builder = TripPlanParameters.builder().withFrom(place); - return places - .stream() - .filter(p -> !p.equals(place)) - .map(p -> builder.copy().withTo(p)); - }); + return places.stream().flatMap(place -> { + var builder = TripPlanParameters.builder().withFrom(place); + return places + .stream() + .filter(p -> !p.equals(place)) + .map(p -> builder.copy().withTo(p)); + }); } } diff --git a/application/src/test/java/org/opentripplanner/standalone/config/BuildConfigTest.java b/application/src/test/java/org/opentripplanner/standalone/config/BuildConfigTest.java index 1c576b7ebf9..2279c659087 100644 --- a/application/src/test/java/org/opentripplanner/standalone/config/BuildConfigTest.java +++ b/application/src/test/java/org/opentripplanner/standalone/config/BuildConfigTest.java @@ -8,8 +8,10 @@ import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; import com.fasterxml.jackson.databind.JsonNode; +import java.util.List; import java.util.Set; import org.junit.jupiter.api.Test; +import org.opentripplanner.osm.model.CompoundRefTagGroup; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; class BuildConfigTest { @@ -44,6 +46,20 @@ public void boardingLocationRefs() { assertEquals(Set.of("a-ha", "royksopp"), subject.boardingLocationTags); } + @Test + public void elevatorRefTags() { + var node = jsonNodeForTest( + "{ 'elevatorRefTags' : [ {'tagGroup': ['ref']}, {'tagGroup': ['manufacturer', 'ref']} ] }" + ); + + var subject = new BuildConfig(node, "Test", false); + + assertEquals( + List.of(CompoundRefTagGroup.of("ref"), CompoundRefTagGroup.of("manufacturer", "ref")), + subject.elevatorRefTags + ); + } + @Test public void fareService() { var node = jsonNodeForTest("{ 'fares' : \"highestFareInFreeTransferWindow\" }"); diff --git a/application/src/test/java/org/opentripplanner/standalone/config/ExampleConfigTest.java b/application/src/test/java/org/opentripplanner/standalone/config/ExampleConfigTest.java index 2abe60d8e00..5967657840f 100644 --- a/application/src/test/java/org/opentripplanner/standalone/config/ExampleConfigTest.java +++ b/application/src/test/java/org/opentripplanner/standalone/config/ExampleConfigTest.java @@ -56,7 +56,8 @@ void speedTestConfig(Path filename) { @FilePatternSource( pattern = { - "test/performance/**/otp-config.json", "doc/user/examples/**/" + OTP_CONFIG_FILENAME, + "test/performance/**/otp-config.json", + "doc/user/examples/**/" + OTP_CONFIG_FILENAME, } ) @ParameterizedTest(name = "Check validity of {0}") @@ -88,8 +89,10 @@ void failInvalidConfig(Path filename) { private void testConfig(Path path, Consumer buildConfig) { try { var json = Files.readString(path); - var replaced = EnvironmentVariableReplacer.insertVariables(json, json, ignored -> - "some-value" + var replaced = EnvironmentVariableReplacer.insertVariables( + json, + json, + ignored -> "some-value" ); var node = JsonSupport.jsonNodeFromString(replaced); var a = new NodeAdapter(node, path.toString()); diff --git a/application/src/test/java/org/opentripplanner/standalone/config/framework/json/NodeAdapterTest.java b/application/src/test/java/org/opentripplanner/standalone/config/framework/json/NodeAdapterTest.java index 2108ae3e7fa..41e1874343a 100644 --- a/application/src/test/java/org/opentripplanner/standalone/config/framework/json/NodeAdapterTest.java +++ b/application/src/test/java/org/opentripplanner/standalone/config/framework/json/NodeAdapterTest.java @@ -198,9 +198,9 @@ void asEnumWithIllegalPropertySet() { {error-message} Parameter: skim.albin. Source: Test. {error-message} Parameter: key. Source: Test. """.replace( - "{error-message}", - "The enum value 'NONE_EXISTING_ENUM_VALUE' is not legal. Expected one of [A, B, A_B_C]." - ), + "{error-message}", + "The enum value 'NONE_EXISTING_ENUM_VALUE' is not legal. Expected one of [A, B, A_B_C]." + ), log.toString() ); } @@ -321,7 +321,10 @@ void asFeedScopedIds() { assertEquals("[]", subject.of("missing-key").asFeedScopedIds(List.of()).toString()); assertEquals( "[C:12]", - subject.of("missing-key").asFeedScopedIds(List.of(new FeedScopedId("C", "12"))).toString() + subject + .of("missing-key") + .asFeedScopedIds(List.of(new FeedScopedId("C", "12"))) + .toString() ); assertEquals(NON_UNUSED_PARAMETERS, unusedParams(subject)); } diff --git a/application/src/test/java/org/opentripplanner/standalone/configure/RequestScopedFactoryTest.java b/application/src/test/java/org/opentripplanner/standalone/configure/RequestScopedFactoryTest.java index 3a64033cc8b..7f3d4b49364 100644 --- a/application/src/test/java/org/opentripplanner/standalone/configure/RequestScopedFactoryTest.java +++ b/application/src/test/java/org/opentripplanner/standalone/configure/RequestScopedFactoryTest.java @@ -47,7 +47,6 @@ import org.opentripplanner.service.vehiclerental.internal.DefaultVehicleRentalRepository; import org.opentripplanner.service.vehiclerental.internal.DefaultVehicleRentalService; import org.opentripplanner.service.worldenvelope.WorldEnvelopeService; -import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.standalone.api.TestServerContext; import org.opentripplanner.standalone.config.DebugUiConfig; import org.opentripplanner.standalone.config.RouterConfig; @@ -59,7 +58,7 @@ import org.opentripplanner.transfer.regular.TransferServiceTestFactory; import org.opentripplanner.transfer.regular.internal.DefaultTransferRepository; import org.opentripplanner.transfer.regular.internal.TransferIndex; -import org.opentripplanner.transit.model.calendar.DefaultTripCalendars; +import org.opentripplanner.transit.model.calendar.TripCalendars; import org.opentripplanner.transit.repository.DefaultTimetableRepository; import org.opentripplanner.transit.repository.TimetableRepository; import org.opentripplanner.transit.repository.TimetableRepositoryLifecycle; @@ -70,11 +69,11 @@ /** * Verifies the real Dagger scoping added for issue #7441: bindings inside one {@link * RequestScopedFactory} build (one simulated HTTP request) are cached and shared, while two - * separate builds (two requests) get independent instances. Since Step 3, {@link - * OtpServerRequestContext} itself is one of those bindings, so this test's root {@code - * TestFactory} has to feed every dependency {@link RequestScopedModule#serverRequestContext} needs - * — reusing the same construction recipes as {@link TestServerContext} rather than duplicating - * them. + * separate builds (two requests) get independent instances. {@link + * org.opentripplanner.apis.gtfs.GtfsGraphQLRequestContext} is one such binding, so this test's + * root {@code TestFactory} has to feed every dependency {@link + * RequestScopedModule#graphQLRequestContext} needs — reusing the same construction recipes as + * {@link TestServerContext} rather than duplicating them. */ class RequestScopedFactoryTest { @@ -84,7 +83,7 @@ void requestScopedBindingsAreCachedWithinOneRequestButNotAcrossRequests() { var repositoryRegistry = TransactionFactory.createRepositoryRegistry(); var timetableSnapshot = new DefaultTimetableRepository( RaptorTransitDataTestFactory.empty(), - new DefaultTripCalendars() + TripCalendars.empty() ); var timetableRepositoryHandle = repositoryRegistry.registerRepositorySnapshot( timetableSnapshot, @@ -165,15 +164,17 @@ public void configure(JsonNode config) {} var requestOne = factory.requestScopedFactoryBuilder().build(); assertThat(requestOne.transitService()).isSameInstanceAs(requestOne.transitService()); assertThat(requestOne.transactionScope()).isSameInstanceAs(requestOne.transactionScope()); - assertThat(requestOne.createServerContext()).isSameInstanceAs(requestOne.createServerContext()); - assertThat(requestOne.createServerContext().transitService()).isSameInstanceAs( + assertThat(requestOne.graphQLRequestContext()).isSameInstanceAs( + requestOne.graphQLRequestContext() + ); + assertThat(requestOne.graphQLRequestContext().transitService()).isSameInstanceAs( requestOne.transitService() ); var requestTwo = factory.requestScopedFactoryBuilder().build(); assertThat(requestOne.transitService()).isNotSameInstanceAs(requestTwo.transitService()); - assertThat(requestOne.createServerContext()).isNotSameInstanceAs( - requestTwo.createServerContext() + assertThat(requestOne.graphQLRequestContext()).isNotSameInstanceAs( + requestTwo.graphQLRequestContext() ); } diff --git a/application/src/test/java/org/opentripplanner/standalone/server/AlertMetricsTest.java b/application/src/test/java/org/opentripplanner/standalone/server/AlertMetricsTest.java index 555962b3547..b387e50b1a0 100644 --- a/application/src/test/java/org/opentripplanner/standalone/server/AlertMetricsTest.java +++ b/application/src/test/java/org/opentripplanner/standalone/server/AlertMetricsTest.java @@ -41,9 +41,9 @@ void registerMultiGauge() { binder.recordMetrics(); var expected = """ - alerts(GAUGE)[feedId='F', severity='INFO']; value=1.0 - alerts(GAUGE)[effect='DETOUR', feedId='F']; value=1.0 - """.trim(); + alerts(GAUGE)[feedId='F', severity='INFO']; value=1.0 + alerts(GAUGE)[effect='DETOUR', feedId='F']; value=1.0 + """.trim(); assertEquals(expected, registry.getMetersAsString()); } diff --git a/application/src/test/java/org/opentripplanner/standalone/server/DaggerToJerseyBridgeTest.java b/application/src/test/java/org/opentripplanner/standalone/server/DaggerToJerseyBridgeTest.java index 929caa4e2f2..26385c59b5c 100644 --- a/application/src/test/java/org/opentripplanner/standalone/server/DaggerToJerseyBridgeTest.java +++ b/application/src/test/java/org/opentripplanner/standalone/server/DaggerToJerseyBridgeTest.java @@ -10,7 +10,7 @@ import org.glassfish.jersey.internal.inject.Injections; import org.glassfish.jersey.process.internal.RequestScope; import org.junit.jupiter.api.Test; -import org.opentripplanner.standalone.api.OtpServerRequestContext; +import org.opentripplanner.routing.api.RoutingService; import org.opentripplanner.standalone.configure.RequestScopedFactory; import org.opentripplanner.transit.service.TransitService; @@ -21,7 +21,7 @@ void allAccessorsWithinOneRequestShareTheSameFactoryInstance() throws Exception Supplier factorySupplier = () -> { RequestScopedFactory factory = mock(RequestScopedFactory.class); when(factory.transitService()).thenReturn(mock(TransitService.class)); - when(factory.createServerContext()).thenReturn(mock(OtpServerRequestContext.class)); + when(factory.routingService()).thenReturn(mock(RoutingService.class)); return factory; }; @@ -37,12 +37,12 @@ void allAccessorsWithinOneRequestShareTheSameFactoryInstance() throws Exception factoryFromRequestA[0] = factory; TransitService expectedTs = factory.transitService(); - OtpServerRequestContext expectedCtx = factory.createServerContext(); + RoutingService expectedRoutingService = factory.routingService(); TransitService ts = im.getInstance(TransitService.class); - OtpServerRequestContext ctx = im.getInstance(OtpServerRequestContext.class); + RoutingService routingService = im.getInstance(RoutingService.class); assertSame(expectedTs, ts); - assertSame(expectedCtx, ctx); + assertSame(expectedRoutingService, routingService); assertSame(factory, im.getInstance(RequestScopedFactory.class)); }); diff --git a/application/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java b/application/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java index 1643d1104b3..7b100bee642 100644 --- a/application/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java +++ b/application/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java @@ -37,6 +37,8 @@ import org.opentripplanner.street.model.StreetMode; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.test.support.ResourceLoader; +import org.opentripplanner.transfer.regular.TransferServiceTestFactory; +import org.opentripplanner.transit.service.TransitRepository; public class BarrierRoutingTest { @@ -149,13 +151,12 @@ private static String computePolyline( .stream() .flatMap(i -> i.legs().stream()) .map( - l -> - () -> - assertEquals( - mapMode(streetMode), - (l instanceof StreetLeg s) ? s.getMode() : null, - "Allow only " + streetMode + " legs" - ) + l -> () -> + assertEquals( + mapMode(streetMode), + l instanceof StreetLeg s ? s.getMode() : null, + "Allow only " + streetMode + " legs" + ) ) ); } @@ -192,15 +193,18 @@ private static String computePolyline( var linkingContextFactory = new LinkingContextFactory(graph, vertexCreationService); var linkingRequest = LinkingContextRequestMapper.map(request); var linkingContext = linkingContextFactory.create(temporaryVerticesContainer, linkingRequest); - var ctx = TestServerContext.ofGraph(graph); + var transitService = TestServerContext.createTransitService( + new TransitRepository(), + TransferServiceTestFactory.defaultTransferRepository() + ); var itineraries = DirectStreetRouter.route( - ctx.graph(), - ctx.transitService(), - ctx.streetLimitationParametersService(), - ctx.vehicleRentalService(), - ctx.streetDetailsService(), - ctx.dataOverlayParameterBindings(), + graph, + transitService, + TestServerContext.createStreetLimitationParametersService(), + TestServerContext.createVehicleRentalService(), + TestServerContext.createStreetDetailsService(), + null, request, linkingContext ); diff --git a/application/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java b/application/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java index a4dfe424280..63de5385af5 100644 --- a/application/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java +++ b/application/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java @@ -26,6 +26,8 @@ import org.opentripplanner.street.model.VehicleRoutingOptimizeType; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.test.support.ResourceLoader; +import org.opentripplanner.transfer.regular.TransferServiceTestFactory; +import org.opentripplanner.transit.service.TransitRepository; public class BicycleRoutingTest { @@ -93,15 +95,18 @@ private static String computePolyline(Graph graph, GenericLocation from, Generic var linkingContextFactory = new LinkingContextFactory(graph, vertexCreationService); var linkingRequest = LinkingContextRequestMapper.map(request); var linkingContext = linkingContextFactory.create(temporaryVerticesContainer, linkingRequest); - var ctx = TestServerContext.ofGraph(graph); + var transitService = TestServerContext.createTransitService( + new TransitRepository(), + TransferServiceTestFactory.defaultTransferRepository() + ); var itineraries = DirectStreetRouter.route( - ctx.graph(), - ctx.transitService(), - ctx.streetLimitationParametersService(), - ctx.vehicleRentalService(), - ctx.streetDetailsService(), - ctx.dataOverlayParameterBindings(), + graph, + transitService, + TestServerContext.createStreetLimitationParametersService(), + TestServerContext.createVehicleRentalService(), + TestServerContext.createStreetDetailsService(), + null, request, linkingContext ); @@ -110,15 +115,13 @@ private static String computePolyline(Graph graph, GenericLocation from, Generic // make sure that we only get BICYCLE legs itineraries.forEach(i -> - i - .legs() - .forEach(l -> { - if (l instanceof StreetLeg stLeg) { - assertEquals(TraverseMode.BICYCLE, stLeg.getMode()); - } else { - fail("Expected StreetLeg (BICYCLE): " + l); - } - }) + i.legs().forEach(l -> { + if (l instanceof StreetLeg stLeg) { + assertEquals(TraverseMode.BICYCLE, stLeg.getMode()); + } else { + fail("Expected StreetLeg (BICYCLE): " + l); + } + }) ); Geometry legGeometry = itineraries.get(0).legs().get(0).legGeometry(); return EncodedPolyline.of(legGeometry).points(); diff --git a/application/src/test/java/org/opentripplanner/street/integration/CarRoutingTest.java b/application/src/test/java/org/opentripplanner/street/integration/CarRoutingTest.java index 9caa36f32c6..78abcfce104 100644 --- a/application/src/test/java/org/opentripplanner/street/integration/CarRoutingTest.java +++ b/application/src/test/java/org/opentripplanner/street/integration/CarRoutingTest.java @@ -27,6 +27,8 @@ import org.opentripplanner.street.model.StreetMode; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.test.support.ResourceLoader; +import org.opentripplanner.transfer.regular.TransferServiceTestFactory; +import org.opentripplanner.transit.service.TransitRepository; public class CarRoutingTest { @@ -142,15 +144,18 @@ private static String computePolyline(Graph graph, GenericLocation from, Generic var linkingContextFactory = new LinkingContextFactory(graph, vertexCreationService); var linkingRequest = LinkingContextRequestMapper.map(request); var linkingContext = linkingContextFactory.create(temporaryVerticesContainer, linkingRequest); - var ctx = TestServerContext.ofGraph(graph); + var transitService = TestServerContext.createTransitService( + new TransitRepository(), + TransferServiceTestFactory.defaultTransferRepository() + ); var itineraries = DirectStreetRouter.route( - ctx.graph(), - ctx.transitService(), - ctx.streetLimitationParametersService(), - ctx.vehicleRentalService(), - ctx.streetDetailsService(), - ctx.dataOverlayParameterBindings(), + graph, + transitService, + TestServerContext.createStreetLimitationParametersService(), + TestServerContext.createVehicleRentalService(), + TestServerContext.createStreetDetailsService(), + null, request, linkingContext ); @@ -158,15 +163,13 @@ private static String computePolyline(Graph graph, GenericLocation from, Generic // make sure that we only get CAR legs itineraries.forEach(i -> - i - .legs() - .forEach(l -> { - if (l instanceof StreetLeg stLeg) { - assertEquals(TraverseMode.CAR, stLeg.getMode()); - } else { - fail("Expected StreetLeg (CAR): " + l); - } - }) + i.legs().forEach(l -> { + if (l instanceof StreetLeg stLeg) { + assertEquals(TraverseMode.CAR, stLeg.getMode()); + } else { + fail("Expected StreetLeg (CAR): " + l); + } + }) ); Geometry legGeometry = itineraries.get(0).legs().get(0).legGeometry(); return EncodedPolyline.of(legGeometry).points(); diff --git a/application/src/test/java/org/opentripplanner/street/integration/EdgeSplittingTest.java b/application/src/test/java/org/opentripplanner/street/integration/EdgeSplittingTest.java index 13838094500..63ec174dcf3 100644 --- a/application/src/test/java/org/opentripplanner/street/integration/EdgeSplittingTest.java +++ b/application/src/test/java/org/opentripplanner/street/integration/EdgeSplittingTest.java @@ -9,7 +9,6 @@ import java.util.Collection; import java.util.HashSet; -import java.util.Set; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.locationtech.jts.linearref.LinearLocation; @@ -25,7 +24,6 @@ import org.opentripplanner.routing.linking.mapping.LinkingContextRequestMapper; import org.opentripplanner.street.geometry.GeometryUtils; import org.opentripplanner.street.graph.Graph; -import org.opentripplanner.street.internal.notes.StreetNotesService; import org.opentripplanner.street.linking.DisposableEdgeCollection; import org.opentripplanner.street.linking.TemporaryVerticesContainer; import org.opentripplanner.street.model.StreetModelForTest; @@ -33,7 +31,6 @@ import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.edge.StreetEdgeBuilder; -import org.opentripplanner.street.model.note.StreetNote; import org.opentripplanner.street.model.vertex.IntersectionVertex; import org.opentripplanner.street.model.vertex.TemporaryStreetLocation; import org.opentripplanner.street.model.vertex.Vertex; @@ -236,13 +233,6 @@ public void testStreetSplittingAlerts() { turns.add(left); turns.add(leftBack); - StreetNote alert = new StreetNote("This is the alert"); - Set alerts = new HashSet<>(); - alerts.add(alert); - - graph.streetNotesService.addStaticNote(left, alert, StreetNotesService.ALWAYS_MATCHER); - graph.streetNotesService.addStaticNote(leftBack, alert, StreetNotesService.ALWAYS_MATCHER); - TemporaryStreetLocation start = StreetModelForTest.createTemporaryStreetLocationForTest( new NonLocalizedString("start"), filter(turns, StreetEdge.class), @@ -262,28 +252,9 @@ public void testStreetSplittingAlerts() { } } - assertEquals(alerts, graph.streetNotesService.getNotes(traversedOne)); assertNotSame(left, traversedOne.getBackEdge().getFromVertex()); assertNotSame(leftBack, traversedOne.getBackEdge().getFromVertex()); - // now, make sure wheelchair alerts are preserved - StreetNote wheelchairAlert = new StreetNote("This is the wheelchair alert"); - Set wheelchairAlerts = new HashSet<>(); - wheelchairAlerts.add(wheelchairAlert); - - graph.streetNotesService.removeStaticNotes(left); - graph.streetNotesService.removeStaticNotes(leftBack); - graph.streetNotesService.addStaticNote( - left, - wheelchairAlert, - StreetNotesService.WHEELCHAIR_MATCHER - ); - graph.streetNotesService.addStaticNote( - leftBack, - wheelchairAlert, - StreetNotesService.WHEELCHAIR_MATCHER - ); - req.withWheelchairEnabled(true); start = StreetModelForTest.createTemporaryStreetLocationForTest( @@ -302,7 +273,6 @@ public void testStreetSplittingAlerts() { } } - assertEquals(wheelchairAlerts, graph.streetNotesService.getNotes(traversedOne)); assertNotSame(left, traversedOne.getBackEdge().getFromVertex()); assertNotSame(leftBack, traversedOne.getBackEdge().getFromVertex()); } diff --git a/application/src/test/java/org/opentripplanner/street/integration/SplitEdgeTurnRestrictionsTest.java b/application/src/test/java/org/opentripplanner/street/integration/SplitEdgeTurnRestrictionsTest.java index ba0310d3600..1ddebd0e72f 100644 --- a/application/src/test/java/org/opentripplanner/street/integration/SplitEdgeTurnRestrictionsTest.java +++ b/application/src/test/java/org/opentripplanner/street/integration/SplitEdgeTurnRestrictionsTest.java @@ -27,6 +27,8 @@ import org.opentripplanner.street.model.StreetMode; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.test.support.ResourceLoader; +import org.opentripplanner.transfer.regular.TransferServiceTestFactory; +import org.opentripplanner.transit.service.TransitRepository; /* * When bus stops are added to graph they split an existing edge in two parts so that an artificial @@ -175,30 +177,31 @@ private static String computeCarPolyline(Graph graph, GenericLocation from, Gene var linkingContextFactory = new LinkingContextFactory(graph, vertexCreationService); var linkingRequest = LinkingContextRequestMapper.map(request); var linkingContext = linkingContextFactory.create(temporaryVerticesContainer, linkingRequest); - var ctx = TestServerContext.ofGraph(graph); + var transitService = TestServerContext.createTransitService( + new TransitRepository(), + TransferServiceTestFactory.defaultTransferRepository() + ); var itineraries = DirectStreetRouter.route( - ctx.graph(), - ctx.transitService(), - ctx.streetLimitationParametersService(), - ctx.vehicleRentalService(), - ctx.streetDetailsService(), - ctx.dataOverlayParameterBindings(), + graph, + transitService, + TestServerContext.createStreetLimitationParametersService(), + TestServerContext.createVehicleRentalService(), + TestServerContext.createStreetDetailsService(), + null, request, linkingContext ); // make sure that we only get CAR legs itineraries.forEach(i -> - i - .legs() - .forEach(l -> { - if (l instanceof StreetLeg stLeg) { - assertEquals(TraverseMode.CAR, stLeg.getMode()); - } else { - fail("Expected StreetLeg (CAR): " + l); - } - }) + i.legs().forEach(l -> { + if (l instanceof StreetLeg stLeg) { + assertEquals(TraverseMode.CAR, stLeg.getMode()); + } else { + fail("Expected StreetLeg (CAR): " + l); + } + }) ); Geometry geometry = itineraries.get(0).legs().get(0).legGeometry(); return EncodedPolyline.of(geometry).points(); diff --git a/application/src/test/java/org/opentripplanner/street/integration/WalkRoutingTest.java b/application/src/test/java/org/opentripplanner/street/integration/WalkRoutingTest.java index 06da746dda6..b2d5001911c 100644 --- a/application/src/test/java/org/opentripplanner/street/integration/WalkRoutingTest.java +++ b/application/src/test/java/org/opentripplanner/street/integration/WalkRoutingTest.java @@ -19,6 +19,8 @@ import org.opentripplanner.street.graph.Graph; import org.opentripplanner.street.linking.TemporaryVerticesContainer; import org.opentripplanner.test.support.ResourceLoader; +import org.opentripplanner.transfer.regular.TransferServiceTestFactory; +import org.opentripplanner.transit.service.TransitRepository; class WalkRoutingTest { @@ -69,14 +71,17 @@ private static List route( var linkingContextFactory = new LinkingContextFactory(graph, vertexCreationService); var linkingRequest = LinkingContextRequestMapper.map(request); var linkingContext = linkingContextFactory.create(temporaryVerticesContainer, linkingRequest); - var ctx = TestServerContext.ofGraph(graph); + var transitService = TestServerContext.createTransitService( + new TransitRepository(), + TransferServiceTestFactory.defaultTransferRepository() + ); return DirectStreetRouter.route( - ctx.graph(), - ctx.transitService(), - ctx.streetLimitationParametersService(), - ctx.vehicleRentalService(), - ctx.streetDetailsService(), - ctx.dataOverlayParameterBindings(), + graph, + transitService, + TestServerContext.createStreetLimitationParametersService(), + TestServerContext.createVehicleRentalService(), + TestServerContext.createStreetDetailsService(), + null, request, linkingContext ); diff --git a/application/src/test/java/org/opentripplanner/test/support/FilePatternArgumentsProvider.java b/application/src/test/java/org/opentripplanner/test/support/FilePatternArgumentsProvider.java index 9c0887c1da7..9bcb08d19b4 100644 --- a/application/src/test/java/org/opentripplanner/test/support/FilePatternArgumentsProvider.java +++ b/application/src/test/java/org/opentripplanner/test/support/FilePatternArgumentsProvider.java @@ -25,7 +25,8 @@ * Check the usages of {@link FilePatternSource} to see examples for how to use. */ class FilePatternArgumentsProvider - implements ArgumentsProvider, AnnotationConsumer { + implements ArgumentsProvider, AnnotationConsumer +{ private List patterns; diff --git a/application/src/test/java/org/opentripplanner/test/support/TestTableParser.java b/application/src/test/java/org/opentripplanner/test/support/TestTableParser.java index 71cde3fe03b..dbfe5887b3c 100644 --- a/application/src/test/java/org/opentripplanner/test/support/TestTableParser.java +++ b/application/src/test/java/org/opentripplanner/test/support/TestTableParser.java @@ -52,7 +52,7 @@ private static Object[] splitLine(String line) { private static String stripComment(String line) { int pos = line.indexOf("#"); - return pos < 0 ? line : (pos == 0 ? "" : line.substring(0, pos).trim()); + return pos < 0 ? line : pos == 0 ? "" : line.substring(0, pos).trim(); } private static Object toValue(String arg) { diff --git a/application/src/test/java/org/opentripplanner/transit/api/request/TripTimeOnDateRequestBuilderTest.java b/application/src/test/java/org/opentripplanner/transit/api/request/TripTimeOnDateRequestBuilderTest.java index 79539c2b3d3..992fb2ee9d2 100644 --- a/application/src/test/java/org/opentripplanner/transit/api/request/TripTimeOnDateRequestBuilderTest.java +++ b/application/src/test/java/org/opentripplanner/transit/api/request/TripTimeOnDateRequestBuilderTest.java @@ -208,7 +208,9 @@ void withNullIncludeAndExcludes() { void withTransitFilters() { var filter = FilterRequest.of() .addSelect( - TripTimeOnDateSelectRequest.of().withAgencies(List.of(new FeedScopedId("F", "A1"))).build() + TripTimeOnDateSelectRequest.of() + .withAgencies(List.of(new FeedScopedId("F", "A1"))) + .build() ) .build(); diff --git a/application/src/test/java/org/opentripplanner/transit/model/_data/TransitRepositoryForTest.java b/application/src/test/java/org/opentripplanner/transit/model/_data/TransitRepositoryForTest.java index 55109abcae4..8a4a6586b7c 100644 --- a/application/src/test/java/org/opentripplanner/transit/model/_data/TransitRepositoryForTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/_data/TransitRepositoryForTest.java @@ -113,7 +113,10 @@ public static Agency agency(String name) { /** Create a valid Bus Route to use in unit tests */ public static RouteBuilder route(String id) { - return Route.of(id(id)).withAgency(AGENCY).withShortName("R" + id).withMode(TransitMode.BUS); + return Route.of(id(id)) + .withAgency(AGENCY) + .withShortName("R" + id) + .withMode(TransitMode.BUS); } /** @@ -125,7 +128,10 @@ public static GroupOfRoutesBuilder groupOfRoutes(String id) { /** Create a valid Bus Route to use in unit tests */ public static RouteBuilder route(FeedScopedId id) { - return Route.of(id).withAgency(AGENCY).withShortName("R" + id).withMode(TransitMode.BUS); + return Route.of(id) + .withAgency(AGENCY) + .withShortName("R" + id) + .withMode(TransitMode.BUS); } public static TripPatternBuilder tripPattern(String id, Route route) { @@ -257,7 +263,7 @@ public Place place(String name, double lat, double lon) { public List stopTimesEvery5Minutes(int count, Trip trip, String time) { var startTime = TimeUtils.time(time); return IntStream.range(0, count) - .mapToObj(seq -> stopTime(trip, (seq + 1) * 10, startTime + (seq * 60 * 5))) + .mapToObj(seq -> stopTime(trip, (seq + 1) * 10, startTime + seq * 60 * 5)) .toList(); } diff --git a/application/src/test/java/org/opentripplanner/transit/model/calendar/TripCalendarsTest.java b/application/src/test/java/org/opentripplanner/transit/model/calendar/TripCalendarsTest.java new file mode 100644 index 00000000000..c90f02bf145 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/transit/model/calendar/TripCalendarsTest.java @@ -0,0 +1,84 @@ +package org.opentripplanner.transit.model.calendar; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +import java.time.LocalDate; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.opentripplanner.core.model.id.FeedScopedIdForTestFactory; +import org.opentripplanner.model.calendar.CalendarServiceData; + +class TripCalendarsTest { + + private static final LocalDate START = LocalDate.of(2024, 1, 10); + private static final LocalDate END = LocalDate.of(2024, 1, 20); + + @Test + void getOrCreateServiceIdForDateOnEmptyCalendarReturnsNull() { + TripCalendars empty = TripCalendars.empty(); + + var result = empty.getOrCreateServiceIdForDate(LocalDate.of(2024, 1, 1), updated -> { + throw new AssertionError("onUpdate must not be called for an empty calendar"); + }); + + assertNull(result, "an empty calendar has no service period, so no date is 'within' it"); + } + + @Test + void getOrCreateServiceIdForDateOutsideServicePeriodReturnsNull() { + TripCalendars calendar = calendarWithRange(); + + assertNull(calendar.getOrCreateServiceIdForDate(START.minusDays(1), throwOnUpdate())); + assertNull(calendar.getOrCreateServiceIdForDate(END.plusDays(1), throwOnUpdate())); + } + + @Test + void getOrCreateServiceIdForDateOnBoundaryDatesSucceeds() { + TripCalendars calendar = calendarWithRange(); + + assertNotNull(calendar.getOrCreateServiceIdForDate(START, updated -> {})); + assertNotNull(calendar.getOrCreateServiceIdForDate(END, updated -> {})); + } + + @Test + void getOrCreateServiceIdForDateRegistersOnceThenReadsThroughOnSubsequentCalls() { + TripCalendars calendar = calendarWithRange(); + LocalDate newDate = START.plusDays(2); + + var updateCount = new int[1]; + var updatedHolder = new TripCalendars[1]; + var serviceId = calendar.getOrCreateServiceIdForDate(newDate, updated -> { + updateCount[0]++; + updatedHolder[0] = updated; + assertFalse(updated.getServiceCodesRunningForDate().get(newDate).isEmpty()); + }); + + assertEquals(1, updateCount[0], "onUpdate must fire exactly once for a genuinely new date"); + TripCalendars updated = updatedHolder[0]; + + // Calling again on the UPDATED instance for the same date must not re-fire onUpdate, since + // the service id is already registered on it — the common, no-op case. + var sameServiceId = updated.getOrCreateServiceIdForDate(newDate, ignored -> { + throw new AssertionError("onUpdate must not fire again for an already-registered date"); + }); + assertEquals(serviceId, sameServiceId); + } + + private static TripCalendars calendarWithRange() { + CalendarServiceData data = new CalendarServiceData(); + data.putServiceDatesForServiceId( + FeedScopedIdForTestFactory.id("CAL_1"), + List.of(START, START.plusDays(1), END) + ); + return TripCalendars.empty().merge(data); + } + + private static java.util.function.Consumer throwOnUpdate() { + return updated -> { + throw new AssertionError("onUpdate must not be called for a date outside the service period"); + }; + } +} diff --git a/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TransitAlertMatcherFactoryTest.java b/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TransitAlertMatcherFactoryTest.java new file mode 100644 index 00000000000..ad9373056fd --- /dev/null +++ b/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TransitAlertMatcherFactoryTest.java @@ -0,0 +1,126 @@ +package org.opentripplanner.transit.model.filter.transit; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.core.model.id.FeedScopedIdForTestFactory.id; + +import java.time.Instant; +import java.util.List; +import java.util.function.UnaryOperator; +import javax.annotation.Nullable; +import org.junit.jupiter.api.Test; +import org.opentripplanner.core.model.id.FeedScopedId; +import org.opentripplanner.core.model.time.TimePeriod; +import org.opentripplanner.routing.alertpatch.AlertCalendar; +import org.opentripplanner.routing.alertpatch.AlertCause; +import org.opentripplanner.routing.alertpatch.AlertEffect; +import org.opentripplanner.routing.alertpatch.AlertSeverity; +import org.opentripplanner.routing.alertpatch.EntitySelector; +import org.opentripplanner.routing.alertpatch.TransitAlert; +import org.opentripplanner.transit.api.request.TransitAlertRequest; +import org.opentripplanner.transit.model.filter.selector.FilterRequest; + +class TransitAlertMatcherFactoryTest { + + private static final FeedScopedId ROUTE_ID = id("F:R1"); + private static final FeedScopedId STOP_ID = id("F:S1"); + + private TransitAlert alert() { + return TransitAlert.of(id("F:A1")) + .addEntity(new EntitySelector.Route(ROUTE_ID)) + .addEntity(new EntitySelector.Stop(STOP_ID)) + .withSeverity(AlertSeverity.SEVERE) + .withCause(AlertCause.WEATHER) + .withEffect(AlertEffect.NO_SERVICE) + .withCalendar( + AlertCalendar.of(TimePeriod.of(Instant.ofEpochSecond(0), Instant.ofEpochSecond(1_000))) + ) + .build(); + } + + @Test + void selectFeedMatches() { + var request = request(select -> select.withFeeds(List.of("F")), null); + assertTrue(TransitAlertMatcherFactory.of(request).match(alert())); + } + + @Test + void selectFeedRejects() { + var request = request(select -> select.withFeeds(List.of("OTHER")), null); + assertFalse(TransitAlertMatcherFactory.of(request).match(alert())); + } + + @Test + void notCauseRejects() { + var request = request(null, select -> select.withCauses(List.of(AlertCause.WEATHER))); + assertFalse(TransitAlertMatcherFactory.of(request).match(alert())); + } + + @Test + void dimensionsWithinASelectorAreCombinedWithAnd() { + var matching = request( + select -> + select + .withSeverityLevels(List.of(AlertSeverity.SEVERE)) + .withCauses(List.of(AlertCause.WEATHER)) + .withEffects(List.of(AlertEffect.NO_SERVICE)), + null + ); + assertTrue(TransitAlertMatcherFactory.of(matching).match(alert())); + + var notMatching = request( + select -> + select + .withSeverityLevels(List.of(AlertSeverity.SEVERE)) + .withCauses(List.of(AlertCause.ACCIDENT)), + null + ); + assertFalse(TransitAlertMatcherFactory.of(notMatching).match(alert())); + } + + @Test + void selectorsAreCombinedWithOr() { + var request = TransitAlertRequest.of() + .withFilters( + List.of( + FilterRequest.of() + .addSelect( + TransitAlertSelectRequest.of().withCauses(List.of(AlertCause.ACCIDENT)).build() + ) + .addSelect( + TransitAlertSelectRequest.of().withCauses(List.of(AlertCause.WEATHER)).build() + ) + .build() + ) + ) + .build(); + assertTrue(TransitAlertMatcherFactory.of(request).match(alert())); + } + + @Test + void timePeriodMatches() { + var range = TimePeriod.of(Instant.ofEpochSecond(0), Instant.ofEpochSecond(2_000)); + var request = request(select -> select.withTimePeriods(List.of(range)), null); + assertTrue(TransitAlertMatcherFactory.of(request).match(alert())); + } + + @Test + void emptyRequestMatchesEverything() { + var request = TransitAlertRequest.of().build(); + assertTrue(TransitAlertMatcherFactory.of(request).match(alert())); + } + + private static TransitAlertRequest request( + @Nullable UnaryOperator select, + @Nullable UnaryOperator not + ) { + var filter = FilterRequest.of(); + if (select != null) { + filter.addSelect(select.apply(TransitAlertSelectRequest.of()).build()); + } + if (not != null) { + filter.addNot(not.apply(TransitAlertSelectRequest.of()).build()); + } + return TransitAlertRequest.of().withFilters(List.of(filter.build())).build(); + } +} diff --git a/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactoryTest.java b/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactoryTest.java index afede6d1c7a..44f9abc4e4b 100644 --- a/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactoryTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactoryTest.java @@ -4,12 +4,16 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.core.model.id.FeedScopedIdForTestFactory.id; +import java.time.Duration; +import java.time.Instant; import java.time.LocalDate; import java.util.List; import java.util.function.BiFunction; +import java.util.function.Function; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.opentripplanner.core.model.time.LocalDateRange; +import org.opentripplanner.core.model.time.TimePeriod; import org.opentripplanner.transit.api.model.FilterValues; import org.opentripplanner.transit.api.request.TripOnServiceDateRequest; import org.opentripplanner.transit.model._data.TransitRepositoryForTest; @@ -32,7 +36,12 @@ class TripOnServiceDateMatcherFactoryTest { private TripOnServiceDate tripOnServiceDateAkt; private TripPattern patternRut; private TripPattern patternAkt; + // The RUT trip runs from 10:00 to 11:00 on its service date, the AKT trip is not running at all + private static final Instant RUT_START = Instant.parse("2024-02-22T10:00:00Z"); + private static final Instant RUT_END = Instant.parse("2024-02-22T11:00:00Z"); + private BiFunction patternResolver; + private Function runningTimeResolver; @BeforeEach void setup() { @@ -110,6 +119,8 @@ void setup() { } return null; }; + runningTimeResolver = tripOnServiceDate -> + tripOnServiceDate.equals(tripOnServiceDateRut) ? TimePeriod.of(RUT_START, RUT_END) : null; } @Test @@ -122,7 +133,8 @@ void testMatchServiceDates() { Matcher matcher = TripOnServiceDateMatcherFactory.of( request, - patternResolver + patternResolver, + runningTimeResolver ); assertTrue(matcher.match(tripOnServiceDateRut)); @@ -145,7 +157,8 @@ void testMatchServiceDateRanges() { Matcher matcher = TripOnServiceDateMatcherFactory.of( request, - patternResolver + patternResolver, + runningTimeResolver ); assertTrue(matcher.match(tripOnServiceDateRut)); @@ -179,7 +192,8 @@ void testMatchMultiple() { Matcher matcher = TripOnServiceDateMatcherFactory.of( request, - patternResolver + patternResolver, + runningTimeResolver ); assertTrue(matcher.match(tripOnServiceDateRut)); @@ -212,7 +226,8 @@ void testMatchMultipleServiceJourneyMatchers() { Matcher matcher = TripOnServiceDateMatcherFactory.of( request, - patternResolver + patternResolver, + runningTimeResolver ); assertTrue(matcher.match(tripOnServiceDateRut)); @@ -240,7 +255,8 @@ void testIncludeExcludeOrder() { Matcher matcher = TripOnServiceDateMatcherFactory.of( request, - patternResolver + patternResolver, + runningTimeResolver ); assertFalse(matcher.match(tripOnServiceDateRut)); @@ -251,12 +267,17 @@ void testIncludeExcludeOrder() { @Test void compositeFilterSelectByAgency() { var filter = FilterRequest.of() - .addSelect(TripOnServiceDateSelectRequest.of().withAgencies(List.of(id("RUT:1"))).build()) + .addSelect( + TripOnServiceDateSelectRequest.of() + .withAgencies(List.of(id("RUT:1"))) + .build() + ) .build(); var request = TripOnServiceDateRequest.of().withFilters(List.of(filter)).build(); Matcher matcher = TripOnServiceDateMatcherFactory.of( request, - patternResolver + patternResolver, + runningTimeResolver ); assertTrue(matcher.match(tripOnServiceDateRut)); @@ -267,12 +288,17 @@ void compositeFilterSelectByAgency() { @Test void compositeFilterNotByAgency() { var filter = FilterRequest.of() - .addNot(TripOnServiceDateSelectRequest.of().withAgencies(List.of(id("RUT:1"))).build()) + .addNot( + TripOnServiceDateSelectRequest.of() + .withAgencies(List.of(id("RUT:1"))) + .build() + ) .build(); var request = TripOnServiceDateRequest.of().withFilters(List.of(filter)).build(); Matcher matcher = TripOnServiceDateMatcherFactory.of( request, - patternResolver + patternResolver, + runningTimeResolver ); assertFalse(matcher.match(tripOnServiceDateRut)); @@ -284,13 +310,22 @@ void compositeFilterNotByAgency() { void compositeFilterSelectIsOrBetweenSelectors() { // Two selectors in select — a trip matching either one should pass var filter = FilterRequest.of() - .addSelect(TripOnServiceDateSelectRequest.of().withAgencies(List.of(id("RUT:1"))).build()) - .addSelect(TripOnServiceDateSelectRequest.of().withAgencies(List.of(id("AKT:1"))).build()) + .addSelect( + TripOnServiceDateSelectRequest.of() + .withAgencies(List.of(id("RUT:1"))) + .build() + ) + .addSelect( + TripOnServiceDateSelectRequest.of() + .withAgencies(List.of(id("AKT:1"))) + .build() + ) .build(); var request = TripOnServiceDateRequest.of().withFilters(List.of(filter)).build(); Matcher matcher = TripOnServiceDateMatcherFactory.of( request, - patternResolver + patternResolver, + runningTimeResolver ); assertTrue(matcher.match(tripOnServiceDateRut)); @@ -302,14 +337,27 @@ void compositeFilterSelectIsOrBetweenSelectors() { void compositeFilterNotOverridesSelect() { // select RUT:1 and AKT:1, but not AKT:1 — AKT:1 should be excluded despite being selected var filter = FilterRequest.of() - .addSelect(TripOnServiceDateSelectRequest.of().withAgencies(List.of(id("RUT:1"))).build()) - .addSelect(TripOnServiceDateSelectRequest.of().withAgencies(List.of(id("AKT:1"))).build()) - .addNot(TripOnServiceDateSelectRequest.of().withAgencies(List.of(id("AKT:1"))).build()) + .addSelect( + TripOnServiceDateSelectRequest.of() + .withAgencies(List.of(id("RUT:1"))) + .build() + ) + .addSelect( + TripOnServiceDateSelectRequest.of() + .withAgencies(List.of(id("AKT:1"))) + .build() + ) + .addNot( + TripOnServiceDateSelectRequest.of() + .withAgencies(List.of(id("AKT:1"))) + .build() + ) .build(); var request = TripOnServiceDateRequest.of().withFilters(List.of(filter)).build(); Matcher matcher = TripOnServiceDateMatcherFactory.of( request, - patternResolver + patternResolver, + runningTimeResolver ); assertTrue(matcher.match(tripOnServiceDateRut)); @@ -321,15 +369,24 @@ void compositeFilterNotOverridesSelect() { void multipleFiltersAreOred() { // Two separate filters — a trip matching either filter should pass var filterRut = FilterRequest.of() - .addSelect(TripOnServiceDateSelectRequest.of().withAgencies(List.of(id("RUT:1"))).build()) + .addSelect( + TripOnServiceDateSelectRequest.of() + .withAgencies(List.of(id("RUT:1"))) + .build() + ) .build(); var filterAkt = FilterRequest.of() - .addSelect(TripOnServiceDateSelectRequest.of().withAgencies(List.of(id("AKT:1"))).build()) + .addSelect( + TripOnServiceDateSelectRequest.of() + .withAgencies(List.of(id("AKT:1"))) + .build() + ) .build(); var request = TripOnServiceDateRequest.of().withFilters(List.of(filterRut, filterAkt)).build(); Matcher matcher = TripOnServiceDateMatcherFactory.of( request, - patternResolver + patternResolver, + runningTimeResolver ); assertTrue(matcher.match(tripOnServiceDateRut)); @@ -347,7 +404,8 @@ void testMatchPatterns() { Matcher matcher = TripOnServiceDateMatcherFactory.of( request, - patternResolver + patternResolver, + runningTimeResolver ); assertTrue(matcher.match(tripOnServiceDateRut)); @@ -366,7 +424,8 @@ void testMatchPatternsExcludesUnresolvedPattern() { // A resolver that cannot resolve a pattern (returns null) must not match the filter. Matcher matcher = TripOnServiceDateMatcherFactory.of( request, - (trip, serviceDate) -> null + (trip, serviceDate) -> null, + tripOnServiceDate -> null ); assertFalse(matcher.match(tripOnServiceDateRut)); @@ -387,7 +446,8 @@ void testMatchPatternAndServiceDate() { Matcher matcher = TripOnServiceDateMatcherFactory.of( request, - patternResolver + patternResolver, + runningTimeResolver ); // Same pattern, but only the trip on the matching service date passes. @@ -395,4 +455,115 @@ void testMatchPatternAndServiceDate() { assertFalse(matcher.match(tripOnServiceDateRut2)); assertFalse(matcher.match(tripOnServiceDateAkt)); } + + @Test + void matchesTripRunningInsidePeriod() { + assertTrue( + matcher( + TimePeriod.of(RUT_START.minus(Duration.ofMinutes(1)), RUT_END.plus(Duration.ofMinutes(1))) + ).match(tripOnServiceDateRut) + ); + } + + @Test + void matchesTripOverlappingPeriod() { + // The trip arrives one minute before the period ends + assertTrue( + matcher( + TimePeriod.of(RUT_END.minus(Duration.ofMinutes(1)), RUT_END.plus(Duration.ofHours(1))) + ).match(tripOnServiceDateRut) + ); + // The trip departs one minute after the period starts + assertTrue( + matcher( + TimePeriod.of(RUT_START.minus(Duration.ofHours(1)), RUT_START.plus(Duration.ofMinutes(1))) + ).match(tripOnServiceDateRut) + ); + } + + @Test + void doesNotMatchTripArrivingExactlyAtStartOfPeriod() { + // The end of the running time of a trip is exclusive + assertFalse(matcher(TimePeriod.of(RUT_END, null)).match(tripOnServiceDateRut)); + } + + @Test + void doesNotMatchTripDepartingExactlyAtEndOfPeriod() { + // The end of the period is exclusive + assertFalse(matcher(TimePeriod.of(null, RUT_START)).match(tripOnServiceDateRut)); + } + + @Test + void doesNotMatchTripOutsidePeriod() { + assertFalse( + matcher(TimePeriod.of(RUT_END.plusSeconds(1), RUT_END.plus(Duration.ofHours(1)))).match( + tripOnServiceDateRut + ) + ); + } + + @Test + void matchesOpenEndedPeriods() { + assertTrue(matcher(TimePeriod.ofUnbounded()).match(tripOnServiceDateRut)); + } + + @Test + void matchesTripWithOpenEndedRunningTime() { + // A trip whose running time has no known end is running indefinitely + runningTimeResolver = tripOnServiceDate -> + tripOnServiceDate.equals(tripOnServiceDateRut) ? TimePeriod.of(RUT_START, null) : null; + + assertTrue( + matcher(TimePeriod.of(RUT_END.plus(Duration.ofHours(1)), null)).match(tripOnServiceDateRut) + ); + assertFalse( + matcher(TimePeriod.of(null, RUT_START.minusSeconds(1))).match(tripOnServiceDateRut) + ); + } + + @Test + void doesNotMatchTripWithUnresolvableRunningTime() { + assertFalse(matcher(TimePeriod.ofUnbounded()).match(tripOnServiceDateAkt)); + } + + @Test + void matchesSelectorRunningTimePeriods() { + var filter = FilterRequest.of() + .addSelect( + TripOnServiceDateSelectRequest.of() + .withRunningTimePeriods(List.of(TimePeriod.of(RUT_START, RUT_END))) + .build() + ) + .build(); + var request = TripOnServiceDateRequest.of().withFilters(List.of(filter)).build(); + var matcher = TripOnServiceDateMatcherFactory.of(request, patternResolver, runningTimeResolver); + + assertTrue(matcher.match(tripOnServiceDateRut)); + assertFalse(matcher.match(tripOnServiceDateRut2)); + assertFalse(matcher.match(tripOnServiceDateAkt)); + } + + @Test + void serviceDateAndRunningTimeAreAnded() { + var request = TripOnServiceDateRequest.of() + .withIncludeRunningTimePeriods( + FilterValues.ofRequired("runningTimePeriods", List.of(TimePeriod.ofUnbounded())) + ) + .withIncludeServiceDates( + FilterValues.ofRequired("serviceDates", List.of(LocalDate.of(2024, 2, 23))) + ) + .build(); + var matcher = TripOnServiceDateMatcherFactory.of(request, patternResolver, runningTimeResolver); + + // The running time of the trip on 2024-02-23 cannot be resolved, so it does not match + assertFalse(matcher.match(tripOnServiceDateRut)); + assertFalse(matcher.match(tripOnServiceDateRut2)); + } + + private Matcher matcher(TimePeriod period) { + var request = TripOnServiceDateRequest.of() + .withIncludeRunningTimePeriods(FilterValues.ofRequired("runningTimePeriods", List.of(period))) + .build(); + return TripOnServiceDateMatcherFactory.of(request, patternResolver, runningTimeResolver); + } } diff --git a/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TripTimeOnDateMatcherFactoryTest.java b/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TripTimeOnDateMatcherFactoryTest.java index bc71471c02e..729d16ac123 100644 --- a/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TripTimeOnDateMatcherFactoryTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TripTimeOnDateMatcherFactoryTest.java @@ -5,11 +5,13 @@ import static org.opentripplanner.transit.model._data.TransitRepositoryForTest.agency; import static org.opentripplanner.transit.model._data.TransitRepositoryForTest.route; +import java.time.Duration; import java.time.Instant; import java.time.LocalDate; import java.util.List; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.opentripplanner.core.model.time.TimePeriod; import org.opentripplanner.model.TripTimeOnDate; import org.opentripplanner.transit.api.request.CancellationPolicy; import org.opentripplanner.transit.api.request.TripTimeOnDateRequest; @@ -648,6 +650,80 @@ void onlyCancellationsExcludesScheduledTripTimes() { assertFalse(matcher.match(tripTimeOnDate(ROUTE_1))); } + @Test + void includeCallTimePeriodOverlapping() { + var request = request() + .withIncludeCallTimePeriods( + List.of( + TimePeriod.of( + Instant.EPOCH.plus(Duration.ofHours(9)), + Instant.EPOCH.plus(Duration.ofHours(11)) + ) + ) + ) + .build(); + var matcher = TripTimeOnDateMatcherFactory.of(request); + + // The vehicle visits the first stop at 10:00 after the epoch + assertTrue(matcher.match(tripTimeOnDate(ROUTE_1))); + } + + @Test + void includeCallTimePeriodNotOverlapping() { + var request = request() + .withIncludeCallTimePeriods( + List.of( + TimePeriod.of( + Instant.EPOCH.plus(Duration.ofHours(11)), + Instant.EPOCH.plus(Duration.ofHours(12)) + ) + ) + ) + .build(); + var matcher = TripTimeOnDateMatcherFactory.of(request); + + assertFalse(matcher.match(tripTimeOnDate(ROUTE_1))); + } + + @Test + void includeCallTimePeriodMatchesVisitAtStopAndNotWholeTrip() { + // The trip runs from 10:00 to 10:05, so the period is within the trip's running time but the + // vehicle visits neither of the stops during it. + var request = request() + .withIncludeCallTimePeriods( + List.of( + TimePeriod.of( + Instant.EPOCH.plus(Duration.ofHours(10)).plus(Duration.ofMinutes(1)), + Instant.EPOCH.plus(Duration.ofHours(10)).plus(Duration.ofMinutes(4)) + ) + ) + ) + .build(); + var matcher = TripTimeOnDateMatcherFactory.of(request); + + assertFalse(matcher.match(tripTimeOnDate(ROUTE_1, 0))); + assertFalse(matcher.match(tripTimeOnDate(ROUTE_1, 1))); + } + + @Test + void includeCallTimePeriodMatchesLaterStopOnly() { + // The period only contains the visit at the second stop at 10:05 + var request = request() + .withIncludeCallTimePeriods( + List.of( + TimePeriod.of( + Instant.EPOCH.plus(Duration.ofHours(10)).plus(Duration.ofMinutes(1)), + Instant.EPOCH.plus(Duration.ofHours(10)).plus(Duration.ofMinutes(10)) + ) + ) + ) + .build(); + var matcher = TripTimeOnDateMatcherFactory.of(request); + + assertFalse(matcher.match(tripTimeOnDate(ROUTE_1, 0))); + assertTrue(matcher.match(tripTimeOnDate(ROUTE_1, 1))); + } + private static TripTimeOnDateRequestBuilder request() { return TripTimeOnDateRequest.of(List.of(STOP)).withTime(Instant.EPOCH); } @@ -658,13 +734,17 @@ private static TripPattern pattern(Route route) { .build(); } - private static TripTimeOnDate tripTimeOnDate(Route route1) { - final TripPattern pattern = pattern(route1); + private static TripTimeOnDate tripTimeOnDate(Route route) { + return tripTimeOnDate(route, 0); + } + + private static TripTimeOnDate tripTimeOnDate(Route route, int stopPosition) { + final TripPattern pattern = pattern(route); var tripTimes = ScheduledTripTimes.of() - .withTrip(TransitRepositoryForTest.trip("t1").withRoute(route1).build()) + .withTrip(TransitRepositoryForTest.trip("t1").withRoute(route).build()) .withArrivalTimes("10:00 10:05") .withDepartureTimes("10:00 10:05") .build(); - return new TripTimeOnDate(tripTimes, 0, pattern, DATE, Instant.EPOCH); + return new TripTimeOnDate(tripTimes, stopPosition, pattern, DATE, Instant.EPOCH); } } diff --git a/application/src/test/java/org/opentripplanner/transit/model/framework/EntityByIdTest.java b/application/src/test/java/org/opentripplanner/transit/model/framework/EntityByIdTest.java index 88bd876e96e..be23c13f591 100644 --- a/application/src/test/java/org/opentripplanner/transit/model/framework/EntityByIdTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/framework/EntityByIdTest.java @@ -95,7 +95,8 @@ public TransitBuilder copy() { } private static class TestEntityBuilder - extends AbstractEntityBuilder { + extends AbstractEntityBuilder + { TestEntityBuilder(TestEntity testEntity) { super(testEntity); diff --git a/application/src/test/java/org/opentripplanner/transit/model/network/StopPatternTest.java b/application/src/test/java/org/opentripplanner/transit/model/network/StopPatternTest.java index d204ab43b8c..e8dd4a97b45 100644 --- a/application/src/test/java/org/opentripplanner/transit/model/network/StopPatternTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/network/StopPatternTest.java @@ -101,7 +101,10 @@ void replaceStops() { assertEquals(List.of(s1, s2, s3), pattern.getStops()); - var updated = pattern.copyOf().replaceStops(Map.of(0, s4, 2, s4)).build(); + var updated = pattern + .copyOf() + .replaceStops(Map.of(0, s4, 2, s4)) + .build(); assertEquals(List.of(s4, s2, s4), updated.getStops()); } diff --git a/application/src/test/java/org/opentripplanner/transit/model/site/AreaStopTest.java b/application/src/test/java/org/opentripplanner/transit/model/site/AreaStopTest.java index af78d5e3449..b13b0a191c7 100644 --- a/application/src/test/java/org/opentripplanner/transit/model/site/AreaStopTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/site/AreaStopTest.java @@ -78,7 +78,11 @@ void sameAs() { assertFalse(SUBJECT.sameAs(SUBJECT.copy().withUrl(new NonLocalizedString("X")).build())); assertFalse(SUBJECT.sameAs(SUBJECT.copy().withZoneId("X").build())); assertFalse( - SUBJECT.sameAs(SUBJECT.copy().withGeometry(GeometryUtils.makeLineString(0, 0, 0, 2)).build()) + SUBJECT.sameAs( + SUBJECT.copy() + .withGeometry(GeometryUtils.makeLineString(0, 0, 0, 2)) + .build() + ) ); } } diff --git a/application/src/test/java/org/opentripplanner/transit/model/timetable/EstimatedTimeTest.java b/application/src/test/java/org/opentripplanner/transit/model/timetable/EstimatedTimeTest.java new file mode 100644 index 00000000000..a9018a982e5 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/transit/model/timetable/EstimatedTimeTest.java @@ -0,0 +1,43 @@ +package org.opentripplanner.transit.model.timetable; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.time.Duration; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import org.junit.jupiter.api.Test; + +class EstimatedTimeTest { + + private static final ZonedDateTime SCHEDULED = ZonedDateTime.of( + 2025, + 1, + 15, + 10, + 0, + 0, + 0, + ZoneId.of("Europe/Helsinki") + ); + + @Test + void delayedVehicleIsLaterThanScheduled() { + var estimate = EstimatedTime.of(SCHEDULED, 120); + assertEquals(SCHEDULED.plusMinutes(2), estimate.time()); + assertEquals(Duration.ofMinutes(2), estimate.delay()); + } + + @Test + void earlyVehicleIsEarlierThanScheduled() { + var estimate = EstimatedTime.of(SCHEDULED, -60); + assertEquals(SCHEDULED.minusMinutes(1), estimate.time()); + assertEquals(Duration.ofMinutes(-1), estimate.delay()); + } + + @Test + void onTimeVehicle() { + var estimate = EstimatedTime.of(SCHEDULED, 0); + assertEquals(SCHEDULED, estimate.time()); + assertEquals(Duration.ZERO, estimate.delay()); + } +} diff --git a/application/src/test/java/org/opentripplanner/transit/model/timetable/TripTimesScheduledRunningTimeTest.java b/application/src/test/java/org/opentripplanner/transit/model/timetable/TripTimesScheduledRunningTimeTest.java new file mode 100644 index 00000000000..6abcb35468a --- /dev/null +++ b/application/src/test/java/org/opentripplanner/transit/model/timetable/TripTimesScheduledRunningTimeTest.java @@ -0,0 +1,106 @@ +package org.opentripplanner.transit.model.timetable; + +import static com.google.common.truth.Truth.assertThat; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import org.junit.jupiter.api.Test; +import org.opentripplanner.model.StopTime; +import org.opentripplanner.transit.model._data.TransitRepositoryForTest; +import org.opentripplanner.utils.time.ServiceDateUtils; +import org.opentripplanner.utils.time.TimeUtils; + +/** + * Tests {@link TripTimes#scheduledRunningTime(Instant)}. + */ +class TripTimesScheduledRunningTimeTest { + + private static final Trip TRIP = TransitRepositoryForTest.trip("Trip-1").build(); + private static final ZoneId OSLO = ZoneId.of("Europe/Oslo"); + + @Test + void runningTimeIsFromFirstDepartureToLastArrival() { + var subject = tripTimes( + new int[] { TimeUtils.time("10:00"), TimeUtils.time("11:25") }, + new int[] { TimeUtils.time("10:01"), TimeUtils.time("11:30") } + ); + + var period = subject.scheduledRunningTime(startOfService(LocalDate.of(2024, 6, 5))); + + assertThat(period).isNotNull(); + assertThat(period.start()).hasValue(instant("2024-06-05T08:01:00Z")); + assertThat(period.end()).hasValue(instant("2024-06-05T09:25:00Z")); + } + + @Test + void runningTimeAfterMidnightIsOnTheNextDay() { + var subject = tripTimes( + new int[] { TimeUtils.time("23:50"), TimeUtils.time("24:30") }, + new int[] { TimeUtils.time("23:50"), TimeUtils.time("24:30") } + ); + + var period = subject.scheduledRunningTime(startOfService(LocalDate.of(2024, 6, 5))); + + assertThat(period).isNotNull(); + assertThat(period.start()).hasValue(instant("2024-06-05T21:50:00Z")); + assertThat(period.end()).hasValue(instant("2024-06-05T22:30:00Z")); + } + + @Test + void runningTimeOnDaylightSavingTimeChangeUsesTheStartOfTheServiceDay() { + // On 2024-03-31 the clock in Oslo is moved forward one hour at 02:00, hence the service day + // starts at 23:00 local time on the previous day. + var subject = tripTimes( + new int[] { TimeUtils.time("01:30"), TimeUtils.time("10:00") }, + new int[] { TimeUtils.time("01:30"), TimeUtils.time("10:00") } + ); + + var period = subject.scheduledRunningTime(startOfService(LocalDate.of(2024, 3, 31))); + + assertThat(period).isNotNull(); + assertThat(period.start()).hasValue(instant("2024-03-30T23:30:00Z")); + assertThat(period.end()).hasValue(instant("2024-03-31T08:00:00Z")); + } + + @Test + void missingArrivalTimeAtLastStopIsNotResolved() { + var subject = tripTimes( + new int[] { TimeUtils.time("10:00"), StopTime.MISSING_VALUE }, + new int[] { TimeUtils.time("10:00"), TimeUtils.time("11:00") } + ); + + assertThat(subject.getScheduledArrivalTime(1)).isEqualTo(StopTime.MISSING_VALUE); + assertThat(subject.scheduledRunningTime(startOfService(LocalDate.of(2024, 6, 5)))).isNull(); + } + + @Test + void arrivalBeforeDepartureIsNotResolved() { + var subject = tripTimes( + new int[] { TimeUtils.time("10:00"), TimeUtils.time("09:00") }, + new int[] { TimeUtils.time("10:00"), TimeUtils.time("09:00") } + ); + + assertThat(subject.scheduledRunningTime(startOfService(LocalDate.of(2024, 6, 5)))).isNull(); + } + + private static Instant startOfService(LocalDate serviceDate) { + return ServiceDateUtils.asStartOfService(serviceDate, OSLO).toInstant(); + } + + private static Instant instant(String text) { + return Instant.parse(text); + } + + /** + * Note: the arrival and departure times of the first and the last stop are the only ones used by + * the running time, the times in between are irrelevant for these tests. + */ + private static TripTimes tripTimes(int[] arrivalTimes, int[] departureTimes) { + return ScheduledTripTimes.of() + .withArrivalTimes(arrivalTimes) + .withDepartureTimes(departureTimes) + .withTrip(TRIP) + .build(); + } +} diff --git a/application/src/test/java/org/opentripplanner/transit/repository/DefaultTimetableRepositoryTest.java b/application/src/test/java/org/opentripplanner/transit/repository/DefaultTimetableRepositoryTest.java index 5285893fcd5..27c6f330e73 100644 --- a/application/src/test/java/org/opentripplanner/transit/repository/DefaultTimetableRepositoryTest.java +++ b/application/src/test/java/org/opentripplanner/transit/repository/DefaultTimetableRepositoryTest.java @@ -28,7 +28,7 @@ import org.opentripplanner.routing.algorithm.raptoradapter.transit.RaptorTransitDataTestFactory; import org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers.TimetableUpdateMapper; import org.opentripplanner.transit.model._data.TransitRepositoryForTest; -import org.opentripplanner.transit.model.calendar.DefaultTripCalendars; +import org.opentripplanner.transit.model.calendar.TripCalendars; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.TripPattern; @@ -79,7 +79,7 @@ public void testCompare() { void testUniqueDirtyTimetablesAfterMultipleUpdates() { DefaultTimetableRepository snapshot = new DefaultTimetableRepository( RaptorTransitDataTestFactory.empty(), - new DefaultTripCalendars() + TripCalendars.empty() ); TripPattern pattern = patternIndex.get(new FeedScopedId(feedId, "1.1")); Trip trip = pattern.scheduledTripsAsStream().findFirst().orElseThrow(); @@ -139,7 +139,7 @@ void testCannotRevertTimetableRepositorySnapshot() { void testClear() { DefaultTimetableRepository snapshot = new DefaultTimetableRepository( RaptorTransitDataTestFactory.empty(), - new DefaultTripCalendars() + TripCalendars.empty() ); TripPattern pattern = patternIndex.get(new FeedScopedId(feedId, "1.1")); Trip trip = pattern.scheduledTripsAsStream().findFirst().orElseThrow(); @@ -200,7 +200,10 @@ void testClearWithAllCollections() { .withStopPattern(TransitRepositoryForTest.stopPattern(STOP_A, STOP_B)) .withScheduledTimeTableBuilder(builder -> builder.addTripTimes( - ScheduledTripTimes.of().withTrip(trip).withDepartureTimes(new int[] { 0, 1 }).build() + ScheduledTripTimes.of() + .withTrip(trip) + .withDepartureTimes(new int[] { 0, 1 }) + .build() ) ) .build(); @@ -225,7 +228,7 @@ void testClearWithAllCollections() { realTimeAddedReplacedByTripOnServiceDateById, new HashMap<>(Map.of(tripIdAndServiceDate, tripOnServiceDate)), patternsForStop, - new DefaultTripCalendars(), + TripCalendars.empty(), RaptorTransitDataTestFactory.empty(), false, new TimetableUpdateMapper() @@ -253,7 +256,7 @@ private static RealTimeTripUpdate createRealTimeTripUpdate(TripPattern pattern, private static DefaultTimetableRepository createCommittedSnapshot() { DefaultTimetableRepository timetableSnapshot = new DefaultTimetableRepository( RaptorTransitDataTestFactory.empty(), - new DefaultTripCalendars() + TripCalendars.empty() ); return timetableSnapshot.commit(true); } diff --git a/application/src/test/java/org/opentripplanner/transit/repository/TimetableRepositoryLifecycleTest.java b/application/src/test/java/org/opentripplanner/transit/repository/TimetableRepositoryLifecycleTest.java index bd5e9ff56c8..6c3b793d6b4 100644 --- a/application/src/test/java/org/opentripplanner/transit/repository/TimetableRepositoryLifecycleTest.java +++ b/application/src/test/java/org/opentripplanner/transit/repository/TimetableRepositoryLifecycleTest.java @@ -14,7 +14,7 @@ import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.routing.algorithm.raptoradapter.transit.RaptorTransitDataTestFactory; import org.opentripplanner.transit.model._data.TransitRepositoryForTest; -import org.opentripplanner.transit.model.calendar.DefaultTripCalendars; +import org.opentripplanner.transit.model.calendar.TripCalendars; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.RealTimeTripUpdate; import org.opentripplanner.transit.model.timetable.ScheduledTripTimes; @@ -86,7 +86,7 @@ public void testPurgeExpiredData( var buffer = new DefaultTimetableRepository( RaptorTransitDataTestFactory.empty(), - new DefaultTripCalendars() + TripCalendars.empty() ); var lifecycle = new TimetableRepositoryLifecycle(buffer, purgeExpiredData, clock::get); diff --git a/application/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java b/application/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java index 366d6a3e711..551238dd389 100644 --- a/application/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java +++ b/application/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java @@ -24,15 +24,16 @@ import org.locationtech.jts.geom.Envelope; import org.opentripplanner.core.model.i18n.I18NString; import org.opentripplanner.core.model.id.FeedScopedId; +import org.opentripplanner.core.model.time.TimePeriod; import org.opentripplanner.model.TripTimeOnDate; import org.opentripplanner.model.calendar.CalendarServiceData; import org.opentripplanner.routing.algorithm.raptoradapter.transit.RaptorTransitDataTestFactory; import org.opentripplanner.street.geometry.WgsCoordinate; +import org.opentripplanner.transit.api.model.FilterValues; import org.opentripplanner.transit.api.request.TripOnServiceDateRequest; import org.opentripplanner.transit.model._data.TransitRepositoryForTest; import org.opentripplanner.transit.model.basic.MainAndSubMode; import org.opentripplanner.transit.model.basic.TransitMode; -import org.opentripplanner.transit.model.calendar.DefaultTripCalendars; import org.opentripplanner.transit.model.filter.selector.FilterRequest; import org.opentripplanner.transit.model.filter.transit.TripOnServiceDateSelectRequest; import org.opentripplanner.transit.model.framework.Deduplicator; @@ -47,6 +48,7 @@ import org.opentripplanner.transit.model.timetable.RealTimeTripUpdate; import org.opentripplanner.transit.model.timetable.ScheduledTripTimes; import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.model.timetable.TripTimesFactory; import org.opentripplanner.transit.repository.DefaultTimetableRepository; @@ -185,10 +187,9 @@ static void setup() { List.of(firstDate, secondDate) ); - var serviceCodes = transitRepository.getServiceCodes(); - serviceCodes.put(SERVICE_ID, SERVICE_CODE); - serviceCodes.put(CALENDAR_ID, SERVICE_CODE); - serviceCodes.put(CALENDAR_ID_TWO, 1); + transitRepository.putServiceCode(SERVICE_ID, SERVICE_CODE); + transitRepository.putServiceCode(CALENDAR_ID, SERVICE_CODE); + transitRepository.putServiceCode(CALENDAR_ID_TWO, 1); transitRepository.addTripPattern(RAIL_PATTERN.getId(), RAIL_PATTERN); transitRepository.addTripPattern(BUS_PATTERN.getId(), BUS_PATTERN); @@ -200,7 +201,7 @@ static void setup() { DefaultTimetableRepository timetableSnapshot = new DefaultTimetableRepository( RaptorTransitDataTestFactory.empty(), - new DefaultTripCalendars() + transitRepository.getTripCalendar() ); TripTimes tripTimes = ScheduledTripTimes.of() .withTrip(TransitRepositoryForTest.trip("123").build()) @@ -329,6 +330,75 @@ void findCanceledNonBusTrips() { var excludedBusTrips = service.findCanceledTrips(busExcludeRequest); assertThat(excludedBusTrips).isEmpty(); } + + /** + * The canceled trip on 2024-08-09 is scheduled to run from 11:30 to 11:40 (Europe/Paris). + */ + @Nested + class RunningTimeFilter { + + private static final LocalDate SERVICE_DAY = LocalDate.of(2024, 8, 9); + private static final Instant DEPARTURE = Instant.parse("2024-08-09T09:30:00Z"); + private static final Instant ARRIVAL = Instant.parse("2024-08-09T09:40:00Z"); + + @Test + void findTripsRunningInPeriod() { + var trips = findByRunningTimePeriod( + TimePeriod.of(DEPARTURE.minusSeconds(600), ARRIVAL.plusSeconds(600)) + ); + assertThat(trips).hasSize(1); + assertEquals(SERVICE_DAY, trips.getFirst().getServiceDate()); + } + + @Test + void findTripsArrivingJustAfterStartOfPeriod() { + var trips = findByRunningTimePeriod( + TimePeriod.of(ARRIVAL.minusSeconds(60), ARRIVAL.plusSeconds(3600)) + ); + assertThat(trips).hasSize(1); + assertEquals(SERVICE_DAY, trips.getFirst().getServiceDate()); + } + + @Test + void endOfPeriodIsExclusive() { + var trips = findByRunningTimePeriod(TimePeriod.of(DEPARTURE.minusSeconds(3600), DEPARTURE)); + assertThat(trips).isEmpty(); + } + + @Test + void findNoTripsOutsidePeriod() { + assertThat( + findByRunningTimePeriod(TimePeriod.of(ARRIVAL.plusSeconds(1), ARRIVAL.plusSeconds(3600))) + ).isEmpty(); + } + + @Test + void serviceDateAndRunningTimeAreCombined() { + var request = TripOnServiceDateRequest.of() + .withIncludeRunningTimePeriods( + FilterValues.ofRequired( + "runningTimePeriods", + List.of(TimePeriod.of(DEPARTURE.minusSeconds(600), ARRIVAL.plusSeconds(600))) + ) + ) + .withIncludeServiceDates( + FilterValues.ofRequired("serviceDates", List.of(LocalDate.of(2024, 8, 8))) + ) + .build(); + + // The trip running within the period is not running on the requested service date + assertThat(service.findCanceledTrips(request)).isEmpty(); + } + + private List findByRunningTimePeriod(TimePeriod period) { + var request = TripOnServiceDateRequest.of() + .withIncludeRunningTimePeriods( + FilterValues.ofRequired("runningTimePeriods", List.of(period)) + ) + .build(); + return service.findCanceledTrips(request); + } + } } @Test diff --git a/application/src/test/java/org/opentripplanner/transit/service/TransitRepositoryTest.java b/application/src/test/java/org/opentripplanner/transit/service/TransitRepositoryTest.java index 24976fc4683..a9d42283cd1 100644 --- a/application/src/test/java/org/opentripplanner/transit/service/TransitRepositoryTest.java +++ b/application/src/test/java/org/opentripplanner/transit/service/TransitRepositoryTest.java @@ -68,9 +68,9 @@ void validateTimeZones() { new GtfsFareServiceFactory(), null ), - ("The graph contains agencies with different time zones. " + + "The graph contains agencies with different time zones. " + "Please configure the one to be used in the " + - BUILD_CONFIG_FILENAME) + BUILD_CONFIG_FILENAME ); } diff --git a/application/src/test/java/org/opentripplanner/transit/speed_test/ResultPrinter.java b/application/src/test/java/org/opentripplanner/transit/speed_test/ResultPrinter.java index dea45747982..6b0b6e69a2f 100644 --- a/application/src/test/java/org/opentripplanner/transit/speed_test/ResultPrinter.java +++ b/application/src/test/java/org/opentripplanner/transit/speed_test/ResultPrinter.java @@ -34,7 +34,7 @@ private ResultPrinter() {} public static String headerLine(String label) { // Make a header width is 100 - int prefixLen = (100 - label.length() - 4); + int prefixLen = 100 - label.length() - 4; var buf = new StringBuilder(100); buf.append("- ".repeat(prefixLen / 2)); if (label.length() % 2 == 1) { @@ -193,7 +193,7 @@ private static String formatResultOk(SpeedTestTimer.Result r) { } private static String str(long value) { - return value < 10_000 ? Long.toString(value) : (value / 1000) + "'"; + return value < 10_000 ? Long.toString(value) : value / 1000 + "'"; } private static String formatLine(String label, int labelWidth, String column) { @@ -235,6 +235,6 @@ private static String logLine(String label, String formatValue, Object... args) } private static String logLine(boolean enable, String label, String formatValues, Object... args) { - return enable ? (String.format("%n%-20s: ", label) + String.format(formatValues, args)) : ""; + return enable ? String.format("%n%-20s: ", label) + String.format(formatValues, args) : ""; } } diff --git a/application/src/test/java/org/opentripplanner/transit/speed_test/SetupHelper.java b/application/src/test/java/org/opentripplanner/transit/speed_test/SetupHelper.java index d20401bc0f5..682decca791 100644 --- a/application/src/test/java/org/opentripplanner/transit/speed_test/SetupHelper.java +++ b/application/src/test/java/org/opentripplanner/transit/speed_test/SetupHelper.java @@ -18,11 +18,12 @@ class SetupHelper { static LoadModel loadGraph(File baseDir, @Nullable URI path) { - File file = path == null - ? OtpDataStore.graphFile(baseDir) - : path.isAbsolute() - ? new File(path) - : new File(baseDir, path.getPath()); + File file = + path == null + ? OtpDataStore.graphFile(baseDir) + : path.isAbsolute() + ? new File(path) + : new File(baseDir, path.getPath()); SerializedGraphObject serializedGraphObject = SerializedGraphObject.load(file); Graph graph = serializedGraphObject.graph; diff --git a/application/src/test/java/org/opentripplanner/transit/speed_test/SpeedTest.java b/application/src/test/java/org/opentripplanner/transit/speed_test/SpeedTest.java index 6769474a24f..e744d7be089 100644 --- a/application/src/test/java/org/opentripplanner/transit/speed_test/SpeedTest.java +++ b/application/src/test/java/org/opentripplanner/transit/speed_test/SpeedTest.java @@ -12,7 +12,6 @@ import java.util.Map; import java.util.function.Predicate; import org.opentripplanner.core.framework.deduplicator.DeduplicatorService; -import org.opentripplanner.ext.fares.service.gtfs.v1.DefaultFareService; import org.opentripplanner.framework.application.OtpAppException; import org.opentripplanner.framework.transaction.TimetableSnapshotParameters; import org.opentripplanner.framework.transaction.api.RepositoryHandle; @@ -24,23 +23,21 @@ import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitTuningParameters; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripSchedule; import org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers.RaptorTransitDataMapper; +import org.opentripplanner.routing.api.RoutingService; import org.opentripplanner.routing.api.response.RoutingResponse; import org.opentripplanner.routing.framework.DebugTimingAggregator; import org.opentripplanner.routing.impl.DelegatingTransitAlertServiceImpl; import org.opentripplanner.routing.linking.VertexLinkerTestFactory; +import org.opentripplanner.routing.service.DefaultRoutingService; import org.opentripplanner.service.realtimevehicles.internal.DefaultRealtimeVehicleRepository; import org.opentripplanner.service.realtimevehicles.internal.RealtimeVehicleRepositoryLifecycle; import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; import org.opentripplanner.service.vehiclerental.internal.DefaultVehicleRentalRepository; import org.opentripplanner.standalone.OtpStartupInfo; -import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.standalone.api.TestServerContext; -import org.opentripplanner.standalone.config.DebugUiConfig; import org.opentripplanner.standalone.config.OtpConfigLoader; import org.opentripplanner.standalone.config.RouterConfig; import org.opentripplanner.standalone.config.routerconfig.RaptorEnvironmentFactory; -import org.opentripplanner.standalone.config.routerconfig.VectorTileConfig; -import org.opentripplanner.standalone.server.DefaultServerRequestContext; import org.opentripplanner.street.graph.Graph; import org.opentripplanner.transfer.regular.TransferRepository; import org.opentripplanner.transfer.regular.TransferServiceTestFactory; @@ -50,6 +47,7 @@ import org.opentripplanner.transit.repository.TimetableRepositorySnapshot; import org.opentripplanner.transit.service.DefaultTransitService; import org.opentripplanner.transit.service.TransitRepository; +import org.opentripplanner.transit.service.TransitService; import org.opentripplanner.transit.speed_test.model.SpeedTestProfile; import org.opentripplanner.transit.speed_test.model.testcase.CsvFileSupport; import org.opentripplanner.transit.speed_test.model.testcase.ExpectedResults; @@ -80,7 +78,8 @@ public class SpeedTest { private final List testCaseDefinitions; private final Map expectedResultsByTcId; private final Map lastSampleResult = new HashMap<>(); - private final OtpServerRequestContext serverContext; + private final RoutingService routingService; + private final TransitService transitService; private final Map> workerResults = new HashMap<>(); private final Map> totalResults = new HashMap<>(); private final CsvFileSupport tcIO; @@ -111,8 +110,6 @@ public SpeedTest( this.testCaseDefinitions = tcIO.readTestCaseDefinitions(); this.expectedResultsByTcId = tcIO.readExpectedResults(); - var transitService = new DefaultTransitService(transitRepository); - TransitTuningParameters tuningParameters = routerConfig.transitTuningConfig(); var scheduledRaptorData = RaptorTransitDataMapper.map( tuningParameters, @@ -126,7 +123,7 @@ public SpeedTest( var registry = TransactionFactory.createRepositoryRegistry(); var timetableSnapshot = new DefaultTimetableRepository( new RaptorTransitData(transitRepository.getRaptorTransitData()), - transitRepository.copyTripCalendarForRealTimeUpdates() + transitRepository.getTripCalendar() ); RepositoryHandle timetableHandle = registry.registerRepositorySnapshot( @@ -185,50 +182,32 @@ public SpeedTest( var vertexLinker = VertexLinkerTestFactory.of(graph); - // Creating raptor transit data should be integrated into the TransitRepository, but for now - // we do it manually here - var transactionScope = registry.scope(); - this.serverContext = new DefaultServerRequestContext( - DebugUiConfig.DEFAULT, - new DefaultFareService(), - routerConfig.flexParameters(), + this.transitService = new DefaultTransitService( + transitRepository, + timetableHandle.repositorySnapshot(transactionScope) + ); + this.routingService = new DefaultRoutingService( + this.transitService, + new DelegatingTransitAlertServiceImpl(), graph, - TestServerContext.createLinkingContextFactory(graph, vertexLinker, transitService), - timer.getRegistry(), - null, raptorConfig, - realtimeVehicleHandle.repositorySnapshot(transactionScope), - List.of(), - routerConfig.routingRequestDefaults(), + timer.getRegistry(), TestServerContext.createStreetLimitationParametersService(), - TransferServiceTestFactory.transferService(transferRepository), - transactionScope, - routerConfig.transitTuningConfig(), - new DefaultTransitService( - transitRepository, - timetableHandle.repositorySnapshot(transactionScope) - ), - new DelegatingTransitAlertServiceImpl(), - null, - null, - VectorTileConfig.DEFAULT, - TestServerContext.createVehicleParkingService(), TestServerContext.createVehicleRentalService(), - vertexLinker, - TestServerContext.createViaTransferResolver(graph, transitService), - TestServerContext.createWorldEnvelopeService(), - null, - null, - null, TestServerContext.createStreetDetailsService(), + TransferServiceTestFactory.transferService(transferRepository), + routerConfig.flexParameters(), + List.of(), null, null, + TestServerContext.createViaTransferResolver(graph, this.transitService), null, null, null, - null, - null + TestServerContext.createLinkingContextFactory(graph, vertexLinker, this.transitService), + routerConfig.transitTuningConfig(), + routerConfig.transitTuningConfig() ); initializeTransferCache(routerConfig.transitTuningConfig(), transitRepository); @@ -370,7 +349,7 @@ private RoutingResponse performRouting(TestCase testCase) { transitRepository.getTimeZone() ); var routingRequest = speedTestRequest.toRouteRequest(); - return serverContext.routingService().route(routingRequest); + return routingService.route(routingRequest); } /* setup helper methods */ @@ -425,7 +404,6 @@ private void saveTestCasesToResultFile() { * Add "static" transit statistics and JVM memory usages to the "timers" logging. */ private void updateTimersWithGlobalCounters() { - final var transitService = serverContext.transitService(); timer.globalCount("transitdata_stops", transitService.listStopLocations().size()); timer.globalCount("transitdata_patterns", transitService.listTripPatterns().size()); timer.globalCount("transitdata_trips", transitService.listTrips().size()); diff --git a/application/src/test/java/org/opentripplanner/transit/speed_test/model/timer/MeterRegistrySetup.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/timer/MeterRegistrySetup.java index 15e5ddd45da..2b058e365a2 100644 --- a/application/src/test/java/org/opentripplanner/transit/speed_test/model/timer/MeterRegistrySetup.java +++ b/application/src/test/java/org/opentripplanner/transit/speed_test/model/timer/MeterRegistrySetup.java @@ -29,8 +29,8 @@ public static Optional getRegistry() { } static Optional influxPassword() { - return Optional.ofNullable(System.getenv(INFLUX_PASSWORD_ENV_VARIABLE)).filter(s -> - !s.isBlank() + return Optional.ofNullable(System.getenv(INFLUX_PASSWORD_ENV_VARIABLE)).filter( + s -> !s.isBlank() ); } diff --git a/application/src/test/java/org/opentripplanner/transit/speed_test/model/timer/SpeedTestTimer.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/timer/SpeedTestTimer.java index 877380e4068..4f6331c8479 100644 --- a/application/src/test/java/org/opentripplanner/transit/speed_test/model/timer/SpeedTestTimer.java +++ b/application/src/test/java/org/opentripplanner/transit/speed_test/model/timer/SpeedTestTimer.java @@ -83,19 +83,17 @@ public void setUp(boolean logResultsByTestCaseCategory) { // record the lowest percentile of times //noinspection NullableProblems - registry - .config() - .meterFilter( - new MeterFilter() { - @Override - public DistributionStatisticConfig configure( - Meter.Id id, - DistributionStatisticConfig config - ) { - return DistributionStatisticConfig.builder().percentiles(0.01).build().merge(config); - } + registry.config().meterFilter( + new MeterFilter() { + @Override + public DistributionStatisticConfig configure( + Meter.Id id, + DistributionStatisticConfig config + ) { + return DistributionStatisticConfig.builder().percentiles(0.01).build().merge(config); } - ); + } + ); } public MeterRegistry getRegistry() { diff --git a/application/src/test/java/org/opentripplanner/transit/speed_test/support/AssertSpeedTestSetup.java b/application/src/test/java/org/opentripplanner/transit/speed_test/support/AssertSpeedTestSetup.java index 5a3081b1a18..a2e5b3758f3 100644 --- a/application/src/test/java/org/opentripplanner/transit/speed_test/support/AssertSpeedTestSetup.java +++ b/application/src/test/java/org/opentripplanner/transit/speed_test/support/AssertSpeedTestSetup.java @@ -31,13 +31,13 @@ public static void assertTestDateHasData( "transitServiceEnd": %s (%s) """.formatted( - numberOfPatternForTestDate, - config.testDate(), - buildConfig.transitServiceStart, - OtpFileNames.BUILD_CONFIG_FILENAME, - buildConfig.transitServiceEnd, - OtpFileNames.BUILD_CONFIG_FILENAME - ) + numberOfPatternForTestDate, + config.testDate(), + buildConfig.transitServiceStart, + OtpFileNames.BUILD_CONFIG_FILENAME, + buildConfig.transitServiceEnd, + OtpFileNames.BUILD_CONFIG_FILENAME + ) ); } } diff --git a/application/src/test/java/org/opentripplanner/updater/alert/gtfs/AlertsUpdateHandlerTest.java b/application/src/test/java/org/opentripplanner/updater/alert/gtfs/AlertsUpdateHandlerTest.java index c1ad4088a76..e424ea57ff1 100644 --- a/application/src/test/java/org/opentripplanner/updater/alert/gtfs/AlertsUpdateHandlerTest.java +++ b/application/src/test/java/org/opentripplanner/updater/alert/gtfs/AlertsUpdateHandlerTest.java @@ -148,9 +148,9 @@ public void testWithUrlTranslations() { .build(); TransitAlert transitAlert = processOneAlert(alert); - List> translations = ((TranslatedString) transitAlert - .url() - .get()).getTranslations(); + List> translations = ( + (TranslatedString) transitAlert.url().get() + ).getTranslations(); assertEquals(2, translations.size()); assertEquals("en", translations.get(0).getKey()); assertEquals("https://www.opentripplanner.org/", translations.get(0).getValue()); @@ -185,9 +185,9 @@ public void testWithHeaderTranslations() { .build(); TransitAlert transitAlert = processOneAlert(alert); - List> translations = ((TranslatedString) transitAlert - .headerText() - .get()).getTranslations(); + List> translations = ( + (TranslatedString) transitAlert.headerText().get() + ).getTranslations(); assertEquals(2, translations.size()); assertEquals("en", translations.get(0).getKey()); assertEquals("Title", translations.get(0).getValue()); @@ -228,9 +228,9 @@ public void testWithDescriptionTranslations() { .build(); TransitAlert transitAlert = processOneAlert(alert); - List> translations = ((TranslatedString) transitAlert - .descriptionText() - .get()).getTranslations(); + List> translations = ( + (TranslatedString) transitAlert.descriptionText().get() + ).getTranslations(); assertEquals(2, translations.size()); assertEquals("en", translations.get(0).getKey()); assertEquals("Description", translations.get(0).getValue()); diff --git a/application/src/test/java/org/opentripplanner/updater/alert/siri/SiriAlertsUpdateHandlerTest.java b/application/src/test/java/org/opentripplanner/updater/alert/siri/SiriAlertsUpdateHandlerTest.java index c045b91facf..e0389a2b472 100644 --- a/application/src/test/java/org/opentripplanner/updater/alert/siri/SiriAlertsUpdateHandlerTest.java +++ b/application/src/test/java/org/opentripplanner/updater/alert/siri/SiriAlertsUpdateHandlerTest.java @@ -190,9 +190,9 @@ public void testSiriSxUpdateForStop() { ); assertFalse( - ((EntitySelector.Stop) entitySelector).stopConditions().contains( - StopCondition.EXCEPTIONAL_STOP - ) + ((EntitySelector.Stop) entitySelector) + .stopConditions() + .contains(StopCondition.EXCEPTIONAL_STOP) ); assertFalse( StopConditionsHelper.matchesStopCondition( @@ -891,7 +891,7 @@ public void testSiriSxUpdateForLineAndStopAndUnknownDirection() { } @Test - public void testSiriSxWithOpenEndedValidity() { + public void testSiriSxWithUnboundedEndValidity() { assertTrue(transitAlertService.getAllAlerts().isEmpty()); final String situationNumber = "TST:SituationNumber:1234"; @@ -910,7 +910,7 @@ public void testSiriSxWithOpenEndedValidity() { period_1.setEndTime(ZonedDateTime.parse("2020-02-01T11:00:00+01:00")); ptSituation.getValidityPeriods().add(period_1); - // Add period with start-, but NO endtime - i.e. open-ended + // Add period with start-, but NO endtime - i.e. an unbounded end HalfOpenTimestampOutputRangeStructure period_2 = new HalfOpenTimestampOutputRangeStructure(); period_2.setStartTime(ZonedDateTime.parse("2020-02-02T10:00:00+01:00")); period_2.setEndTime(null); @@ -990,7 +990,7 @@ private PtSituationElement createPtSituationElement( PtSituationElement element = new PtSituationElement(); element.setCreationTime(ZonedDateTime.now()); element.setProgress(WorkflowStatusEnumeration.OPEN); - if ((startTime != null) || (endTime != null)) { + if (startTime != null || endTime != null) { HalfOpenTimestampOutputRangeStructure period = new HalfOpenTimestampOutputRangeStructure(); if (startTime != null) { @@ -1259,7 +1259,7 @@ private boolean matchesEntity( for (EntitySelector entity : transitAlert.entities()) { if (!foundMatch) { if (entity.key() instanceof EntityKey.StopAndRoute stopAndRoute) { - foundMatch = stopAndRoute.equals((new EntityKey.StopAndRoute(stopId, routeOrTripId))); + foundMatch = stopAndRoute.equals(new EntityKey.StopAndRoute(stopId, routeOrTripId)); } else if (entity instanceof EntitySelector.StopAndTrip stopAndTrip) { foundMatch = stopAndTrip.key().equals(new EntityKey.StopAndTrip(stopId, routeOrTripId)) && diff --git a/application/src/test/java/org/opentripplanner/updater/trip/TripUpdateApplierTest.java b/application/src/test/java/org/opentripplanner/updater/trip/TripUpdateApplierTest.java index 5e143a43d07..ad86c1e300a 100644 --- a/application/src/test/java/org/opentripplanner/updater/trip/TripUpdateApplierTest.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/TripUpdateApplierTest.java @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.routing.algorithm.raptoradapter.transit.RaptorTransitDataTestFactory; import org.opentripplanner.transit.model._data.TransitRepositoryForTest; -import org.opentripplanner.transit.model.calendar.DefaultTripCalendars; +import org.opentripplanner.transit.model.calendar.TripCalendars; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.RegularStop; @@ -75,7 +75,7 @@ class TripUpdateApplierTest { private static DefaultTimetableRepository createBuffer() { return new DefaultTimetableRepository( RaptorTransitDataTestFactory.empty(), - new DefaultTripCalendars() + TripCalendars.empty() ); } diff --git a/application/src/test/java/org/opentripplanner/updater/trip/gtfs/LegacyTimetableRepositoryIntegrationTest.java b/application/src/test/java/org/opentripplanner/updater/trip/gtfs/LegacyTimetableRepositoryIntegrationTest.java index 8704c65120a..cff2fe3ea67 100644 --- a/application/src/test/java/org/opentripplanner/updater/trip/gtfs/LegacyTimetableRepositoryIntegrationTest.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/gtfs/LegacyTimetableRepositoryIntegrationTest.java @@ -24,7 +24,7 @@ import org.opentripplanner._support.time.ZoneIds; import org.opentripplanner.core.model.id.FeedScopedId; import org.opentripplanner.routing.algorithm.raptoradapter.transit.RaptorTransitDataTestFactory; -import org.opentripplanner.transit.model.calendar.DefaultTripCalendars; +import org.opentripplanner.transit.model.calendar.TripCalendars; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.RealTimeTripUpdate; @@ -72,7 +72,7 @@ public void testResolve() { TripPattern pattern = patternIndex.get(new FeedScopedId(feedId, "1.1")); DefaultTimetableRepository resolver = new DefaultTimetableRepository( RaptorTransitDataTestFactory.empty(), - new DefaultTripCalendars() + TripCalendars.empty() ); Timetable scheduled = resolver.resolve(pattern, today); @@ -123,7 +123,7 @@ public void testUpdate() { DefaultTimetableRepository resolver = new DefaultTimetableRepository( RaptorTransitDataTestFactory.empty(), - new DefaultTripCalendars() + TripCalendars.empty() ); Timetable origNow = resolver.resolve(pattern, today); @@ -177,7 +177,7 @@ public void testCommit() { DefaultTimetableRepository resolver = new DefaultTimetableRepository( RaptorTransitDataTestFactory.empty(), - new DefaultTripCalendars() + TripCalendars.empty() ); // only return a new snapshot if there are changes @@ -257,7 +257,7 @@ public void testPurge() { DefaultTimetableRepository resolver = new DefaultTimetableRepository( RaptorTransitDataTestFactory.empty(), - new DefaultTripCalendars() + TripCalendars.empty() ); updateSnapshot(resolver, pattern, tripUpdate, today); updateSnapshot(resolver, pattern, tripUpdate, yesterday); diff --git a/application/src/test/java/org/opentripplanner/updater/trip/gtfs/interpolation/DefaultForwardsDelayInterpolatorTest.java b/application/src/test/java/org/opentripplanner/updater/trip/gtfs/interpolation/DefaultForwardsDelayInterpolatorTest.java index 2fa06fa0883..5ed3e3a5646 100644 --- a/application/src/test/java/org/opentripplanner/updater/trip/gtfs/interpolation/DefaultForwardsDelayInterpolatorTest.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/gtfs/interpolation/DefaultForwardsDelayInterpolatorTest.java @@ -193,13 +193,11 @@ void noDataOnly() { assertTrue(interpolator.interpolateDelay(builder)); // NO_DATA should be propagated forward - builder - .listStopPositions() - .forEach(i -> { - assertEquals(0, builder.getArrivalDelay(i)); - assertEquals(0, builder.getDepartureDelay(i)); - assertEquals(NO_DATA, builder.getStopRealTimeState(i)); - }); + builder.listStopPositions().forEach(i -> { + assertEquals(0, builder.getArrivalDelay(i)); + assertEquals(0, builder.getDepartureDelay(i)); + assertEquals(NO_DATA, builder.getStopRealTimeState(i)); + }); assertNotNull(builder.build()); } diff --git a/application/src/test/java/org/opentripplanner/updater/trip/siri/AddedTripBuilderTest.java b/application/src/test/java/org/opentripplanner/updater/trip/siri/AddedTripBuilderTest.java index 416140073c3..08293f3ccc7 100644 --- a/application/src/test/java/org/opentripplanner/updater/trip/siri/AddedTripBuilderTest.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/siri/AddedTripBuilderTest.java @@ -22,6 +22,7 @@ import org.opentripplanner.core.model.id.FeedScopedIdForTestFactory; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.calendar.CalendarServiceData; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.RaptorTransitDataTestFactory; import org.opentripplanner.transit.model._data.TransitRepositoryForTest; import org.opentripplanner.transit.model.basic.SubMode; import org.opentripplanner.transit.model.basic.TransitMode; @@ -35,6 +36,7 @@ import org.opentripplanner.transit.model.timetable.RealTimeTripTimes; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; +import org.opentripplanner.transit.repository.DefaultTimetableRepository; import org.opentripplanner.transit.service.DefaultTransitService; import org.opentripplanner.transit.service.SiteRepository; import org.opentripplanner.transit.service.TransitRepository; @@ -83,6 +85,7 @@ class AddedTripBuilderTest { private final TransitRepository TRANSIT_MODEL = new TransitRepository(SITE_REPOSITORY); private TransitService transitService; private EntityResolver ENTITY_RESOLVER; + private DefaultTimetableRepository timetableRepository; @BeforeEach void setUp() { @@ -103,16 +106,20 @@ void setUp() { cal_id, List.of(SERVICE_DATE.minusDays(1), SERVICE_DATE, SERVICE_DATE.plusDays(1)) ); - TRANSIT_MODEL.getServiceCodes().put(cal_id, 0); + TRANSIT_MODEL.putServiceCode(cal_id, 0); TRANSIT_MODEL.updateCalendarServiceData(calendarServiceData); // Create transit model index TRANSIT_MODEL.index(); - transitService = new DefaultTransitService(TRANSIT_MODEL); + timetableRepository = new DefaultTimetableRepository( + RaptorTransitDataTestFactory.empty(), + TRANSIT_MODEL.getTripCalendar() + ); + transitService = new DefaultTransitService(TRANSIT_MODEL, timetableRepository); // Create the entity resolver only after the model has been indexed ENTITY_RESOLVER = new EntityResolver( - new DefaultTransitService(TRANSIT_MODEL), + new DefaultTransitService(TRANSIT_MODEL, timetableRepository), TransitRepositoryForTest.FEED_ID ); } @@ -121,6 +128,7 @@ void setUp() { void testAddedTrip() { var tripUpdate = new AddedTripBuilder( transitService, + timetableRepository, DEDUPLICATOR, ENTITY_RESOLVER, AbstractTransitEntity::getId, @@ -172,7 +180,7 @@ void testAddedTrip() { assertTrue( transitService .getServiceCodesRunningForDate(SERVICE_DATE) - .contains(TRANSIT_MODEL.getServiceCodes().get(trip.getServiceId())), + .contains(timetableRepository.getTripCalendars().getServiceCode(trip.getServiceId())), "serviceId should be running on service date" ); TripOnServiceDate tripOnServiceDate = tripUpdate.addedTripOnServiceDate(); @@ -242,6 +250,7 @@ void testAddedTrip() { void testAddedTripOnAddedRoute() { var firstAddedTrip = new AddedTripBuilder( transitService, + timetableRepository, DEDUPLICATOR, ENTITY_RESOLVER, AbstractTransitEntity::getId, @@ -273,6 +282,7 @@ void testAddedTripOnAddedRoute() { var secondAddedTrip = new AddedTripBuilder( transitService, + timetableRepository, DEDUPLICATOR, ENTITY_RESOLVER, AbstractTransitEntity::getId, @@ -316,6 +326,7 @@ void testAddedTripOnAddedRoute() { void testAddedTripOnExistingRoute() { var addedTrip = new AddedTripBuilder( transitService, + timetableRepository, DEDUPLICATOR, ENTITY_RESOLVER, AbstractTransitEntity::getId, @@ -351,6 +362,7 @@ void testAddedTripOnExistingRoute() { void testAddedTripWithoutReplacedRoute() { var addedTrip = new AddedTripBuilder( transitService, + timetableRepository, DEDUPLICATOR, ENTITY_RESOLVER, AbstractTransitEntity::getId, @@ -396,6 +408,7 @@ void testAddedTripWithoutReplacedRoute() { void testAddedTripFailOnMissingServiceId() { var addedTrip = new AddedTripBuilder( transitService, + timetableRepository, DEDUPLICATOR, ENTITY_RESOLVER, AbstractTransitEntity::getId, @@ -450,6 +463,7 @@ void testAddedTripFailOnNonIncreasingDwellTime() { var addedTrip = new AddedTripBuilder( transitService, + timetableRepository, DEDUPLICATOR, ENTITY_RESOLVER, AbstractTransitEntity::getId, @@ -490,6 +504,7 @@ void testAddedTripFailOnTooFewCalls() { ); var addedTrip = new AddedTripBuilder( transitService, + timetableRepository, DEDUPLICATOR, ENTITY_RESOLVER, AbstractTransitEntity::getId, @@ -536,6 +551,7 @@ void testAddedTripFailOnUnknownStop() { ); var addedTrip = new AddedTripBuilder( transitService, + timetableRepository, DEDUPLICATOR, ENTITY_RESOLVER, AbstractTransitEntity::getId, @@ -566,14 +582,12 @@ void testAddedTripFailOnUnknownStop() { } @ParameterizedTest - @CsvSource( - { - "air,AIRPLANE,AIRPLANE,", - "bus,BUS,RAIL,railReplacementBus", - "rail,RAIL,RAIL,replacementRailService", - "ferry,FERRY,RAIL,", - } - ) + @CsvSource({ + "air,AIRPLANE,AIRPLANE,", + "bus,BUS,RAIL,railReplacementBus", + "rail,RAIL,RAIL,replacementRailService", + "ferry,FERRY,RAIL,", + }) void testGetTransportMode( String siriMode, String internalMode, @@ -602,6 +616,7 @@ void testGetTransportMode( void vehicleRefIsSetOnTripTimes() { var tripUpdate = new AddedTripBuilder( transitService, + timetableRepository, DEDUPLICATOR, ENTITY_RESOLVER, AbstractTransitEntity::getId, @@ -633,6 +648,7 @@ void vehicleRefIsSetOnTripTimes() { void vehicleRefIsNullWhenAbsent() { var tripUpdate = new AddedTripBuilder( transitService, + timetableRepository, DEDUPLICATOR, ENTITY_RESOLVER, AbstractTransitEntity::getId, diff --git a/application/src/test/java/org/opentripplanner/updater/trip/siri/EstimatedVehicleJourneyCodeTest.java b/application/src/test/java/org/opentripplanner/updater/trip/siri/EstimatedVehicleJourneyCodeTest.java index 375088a2c2a..c465082b984 100644 --- a/application/src/test/java/org/opentripplanner/updater/trip/siri/EstimatedVehicleJourneyCodeTest.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/siri/EstimatedVehicleJourneyCodeTest.java @@ -8,36 +8,32 @@ class EstimatedVehicleJourneyCodeTest { @ParameterizedTest - @CsvSource( - { - "1234, 1234", - "RUT:ServiceJourney:1234, RUT:ServiceJourney:1234", - "RUT:DatedServiceJourney:1234, RUT:ServiceJourney:1234", - "RUT:Unknown:1234, RUT:Unknown:1234", - "RUT:ServiceJourney:1234:extra, RUT:ServiceJourney:1234:extra", - "RUT:DatedServiceJourney:1234:extra, RUT:ServiceJourney:1234:extra", - } - ) + @CsvSource({ + "1234, 1234", + "RUT:ServiceJourney:1234, RUT:ServiceJourney:1234", + "RUT:DatedServiceJourney:1234, RUT:ServiceJourney:1234", + "RUT:Unknown:1234, RUT:Unknown:1234", + "RUT:ServiceJourney:1234:extra, RUT:ServiceJourney:1234:extra", + "RUT:DatedServiceJourney:1234:extra, RUT:ServiceJourney:1234:extra", + }) void asServiceJourneyId(String code, String expected) { assertEquals(expected, new EstimatedVehicleJourneyCode(code).asServiceJourneyId()); } @ParameterizedTest - @CsvSource( - { - "1234, 1234", - "RUT:ServiceJourney:1234, RUT:DatedServiceJourney:1234", - "RUT:DatedServiceJourney:1234, RUT:DatedServiceJourney:1234", - "RUT:Unknown:1234, RUT:Unknown:1234", - "RUT:ServiceJourney:1234:extra, RUT:DatedServiceJourney:1234:extra", - "RUT:DatedServiceJourney:1234:extra, RUT:DatedServiceJourney:1234:extra", - "\"\" , \"\"", - "::,::", - "::ID, ::ID", - ":ServiceJourney:ID, :DatedServiceJourney:ID", - "NAME_SPACE::, NAME_SPACE::", - } - ) + @CsvSource({ + "1234, 1234", + "RUT:ServiceJourney:1234, RUT:DatedServiceJourney:1234", + "RUT:DatedServiceJourney:1234, RUT:DatedServiceJourney:1234", + "RUT:Unknown:1234, RUT:Unknown:1234", + "RUT:ServiceJourney:1234:extra, RUT:DatedServiceJourney:1234:extra", + "RUT:DatedServiceJourney:1234:extra, RUT:DatedServiceJourney:1234:extra", + "\"\" , \"\"", + "::,::", + "::ID, ::ID", + ":ServiceJourney:ID, :DatedServiceJourney:ID", + "NAME_SPACE::, NAME_SPACE::", + }) void asDatedServiceJourneyId(String code, String expected) { assertEquals(expected, new EstimatedVehicleJourneyCode(code).asDatedServiceJourneyId()); } diff --git a/application/src/test/java/org/opentripplanner/updater/trip/siri/EstimatedVehicleJourneyWrapperTest.java b/application/src/test/java/org/opentripplanner/updater/trip/siri/EstimatedVehicleJourneyWrapperTest.java index d15dd33f761..59fd5e5b9ef 100644 --- a/application/src/test/java/org/opentripplanner/updater/trip/siri/EstimatedVehicleJourneyWrapperTest.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/siri/EstimatedVehicleJourneyWrapperTest.java @@ -185,14 +185,12 @@ void replacedDatedVehicleJourneyRef() { @Test void additionalReplacedDatedVehicleJourneyRefs() { var journey = builder().buildEstimatedVehicleJourney(); - journey - .getAdditionalVehicleJourneyReves() - .add( - new SiriEtBuilder.FramedVehicleRefBuilder() - .withVehicleJourneyRef("REPLACED:2") - .withServiceDate(LocalDate.of(2024, 5, 7)) - .build() - ); + journey.getAdditionalVehicleJourneyReves().add( + new SiriEtBuilder.FramedVehicleRefBuilder() + .withVehicleJourneyRef("REPLACED:2") + .withServiceDate(LocalDate.of(2024, 5, 7)) + .build() + ); var result = EstimatedVehicleJourneyWrapper.of( journey diff --git a/application/src/test/java/org/opentripplanner/updater/trip/siri/ModifiedTripBuilderTest.java b/application/src/test/java/org/opentripplanner/updater/trip/siri/ModifiedTripBuilderTest.java index b7934e1e032..8b8d2fba9e0 100644 --- a/application/src/test/java/org/opentripplanner/updater/trip/siri/ModifiedTripBuilderTest.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/siri/ModifiedTripBuilderTest.java @@ -137,7 +137,7 @@ void setUp() { SERVICE_ID, List.of(SERVICE_DATE.minusDays(1), SERVICE_DATE, SERVICE_DATE.plusDays(1)) ); - transitRepository.getServiceCodes().put(SERVICE_ID, 0); + transitRepository.putServiceCode(SERVICE_ID, 0); transitRepository.updateCalendarServiceData(calendarServiceData); // Create transit model index diff --git a/application/src/test/java/org/opentripplanner/updater/trip/siri/SiriEtBuilder.java b/application/src/test/java/org/opentripplanner/updater/trip/siri/SiriEtBuilder.java index e359d4ad1d9..48400a217d6 100644 --- a/application/src/test/java/org/opentripplanner/updater/trip/siri/SiriEtBuilder.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/siri/SiriEtBuilder.java @@ -174,9 +174,8 @@ public SiriEtBuilder withRecordedCalls( public SiriEtBuilder withEstimatedCalls( Function producer ) { - int offset = evj.getRecordedCalls() == null - ? 0 - : evj.getRecordedCalls().getRecordedCalls().size(); + int offset = + evj.getRecordedCalls() == null ? 0 : evj.getRecordedCalls().getRecordedCalls().size(); var builder = new EstimatedCallsBuilder(localTimeParser, offset); builder = producer.apply(builder); diff --git a/application/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterTest.java b/application/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterTest.java index 3cffa43ec1c..af9ee0233f8 100644 --- a/application/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterTest.java +++ b/application/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterTest.java @@ -1,5 +1,6 @@ package org.opentripplanner.updater.vehicle_parking; +import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.when; @@ -282,7 +283,7 @@ private void runUpdaterOnce() { private void assertVehicleParkingNotLinked() { assertEquals(0, graph.getVerticesOfType(VehicleParkingEntranceVertex.class).size()); - assertEquals(0, graph.getEdgesOfType(StreetVehicleParkingLink.class).size()); - assertEquals(0, graph.getEdgesOfType(VehicleParkingEdge.class).size()); + assertThat(graph.findEdges(StreetVehicleParkingLink.class)).isEmpty(); + assertThat(graph.findEdges(VehicleParkingEdge.class)).isEmpty(); } } diff --git a/application/src/test/java/org/opentripplanner/updater/vehicle_position/RealtimeVehicleMatcherTest.java b/application/src/test/java/org/opentripplanner/updater/vehicle_position/RealtimeVehicleMatcherTest.java index 78daee31721..574ec41cfa4 100644 --- a/application/src/test/java/org/opentripplanner/updater/vehicle_position/RealtimeVehicleMatcherTest.java +++ b/application/src/test/java/org/opentripplanner/updater/vehicle_position/RealtimeVehicleMatcherTest.java @@ -542,7 +542,7 @@ void inferServiceDateCloseToMidnight() { var trip = TransitRepositoryForTest.trip(tripId).build(); var fiveToMidnight = LocalTime.parse("23:55").toSecondOfDay(); - var fivePastMidnight = fiveToMidnight + (10 * 60); + var fivePastMidnight = fiveToMidnight + 10 * 60; var stopTimes = List.of( testModel.stopTime(trip, 0, fiveToMidnight), testModel.stopTime(trip, 1, fivePastMidnight) diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/alerts.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/alerts.json index 0d8445eb8ff..9707baaeba8 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/alerts.json +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/alerts.json @@ -8,7 +8,15 @@ "descriptionDefault": "", "descriptionDe": "", "urlDefault": null, - "urlDe": null + "urlDe": null, + "activityPeriods": [ + { + "start": null, + "end": null + } + ], + "effectiveStartDate": null, + "effectiveEndDate": null }, { "id": "QWxlcnQ6Rjpuby1oZWFkZXI", @@ -17,7 +25,15 @@ "descriptionDefault": "Second string", "descriptionDe": "Zweite Zeichenabfolge", "urlDefault": null, - "urlDe": null + "urlDe": null, + "activityPeriods": [ + { + "start": null, + "end": null + } + ], + "effectiveStartDate": null, + "effectiveEndDate": null }, { "id": "QWxlcnQ6Rjphbi1hbGVydA", @@ -26,7 +42,15 @@ "descriptionDefault": "A description", "descriptionDe": "A description", "urlDefault": "https://example.com", - "urlDe": "https://example.com" + "urlDe": "https://example.com", + "activityPeriods": [ + { + "start": "2023-02-15T12:03:28+01:00", + "end": "2023-02-16T12:03:28+01:00" + } + ], + "effectiveStartDate": 1676459008, + "effectiveEndDate": 1676545408 }, { "id": "QWxlcnQ6Rjpuby1kZXNjcmlwdGlvbg", @@ -35,7 +59,15 @@ "descriptionDefault": "First string", "descriptionDe": "Erste Zeichenabfolge", "urlDefault": null, - "urlDe": null + "urlDe": null, + "activityPeriods": [ + { + "start": null, + "end": null + } + ], + "effectiveStartDate": null, + "effectiveEndDate": null }, { "id": "QWxlcnQ6RjphLXN0YXRpb24tYWxlcnQ", @@ -44,7 +76,23 @@ "descriptionDefault": "This station is currently closed", "descriptionDe": "This station is currently closed", "urlDefault": null, - "urlDe": null + "urlDe": null, + "activityPeriods": [ + { + "start": null, + "end": "2023-02-15T12:03:28+01:00" + }, + { + "start": "2023-02-15T12:03:28+01:00", + "end": "2023-02-16T12:03:28+01:00" + }, + { + "start": "2023-02-16T12:03:28+01:00", + "end": null + } + ], + "effectiveStartDate": null, + "effectiveEndDate": null } ] } diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/alertsConnection.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/alertsConnection.json new file mode 100644 index 00000000000..d3c4632becf --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/alertsConnection.json @@ -0,0 +1,35 @@ +{ + "data": { + "alertsConnection": { + "totalCount": 5, + "pageInfo": { + "hasNextPage": true, + "hasPreviousPage": false + }, + "edges": [ + { + "node": { + "id": "QWxlcnQ6Rjphbi1hbGVydA", + "headerDefault": "A header", + "headerDe": "A header", + "descriptionDefault": "A description", + "descriptionDe": "A description", + "urlDefault": "https://example.com", + "urlDe": "https://example.com" + } + }, + { + "node": { + "id": "QWxlcnQ6RjphLXN0YXRpb24tYWxlcnQ", + "headerDefault": "Station closed", + "headerDe": "Station closed", + "descriptionDefault": "This station is currently closed", + "descriptionDe": "This station is currently closed", + "urlDefault": null, + "urlDe": null + } + } + ] + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/alerts.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/alerts.graphql index 3a5d438e8ef..8d48c4b5981 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/alerts.graphql +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/alerts.graphql @@ -7,5 +7,11 @@ descriptionDe: alertDescriptionText(language: "de") urlDefault: alertUrl urlDe: alertUrl(language: "de") + activityPeriods { + start + end + } + effectiveStartDate + effectiveEndDate } } diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/alertsConnection.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/alertsConnection.graphql new file mode 100644 index 00000000000..d4fa182d7a9 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/alertsConnection.graphql @@ -0,0 +1,20 @@ +{ + alertsConnection(first: 2) { + totalCount + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + id + headerDefault: alertHeaderText + headerDe: alertHeaderText(language: "de") + descriptionDefault: alertDescriptionText + descriptionDe: alertDescriptionText(language: "de") + urlDefault: alertUrl + urlDe: alertUrl(language: "de") + } + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/canceled-trips.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/canceled-trips.graphql index 61fc8f475ce..9ffcf27d700 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/canceled-trips.graphql +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/canceled-trips.graphql @@ -7,6 +7,7 @@ { modes: [BUS] serviceDateRanges: [{ start: "2024-08-09", end: "2024-08-10" }] + runningTimeRanges: [{ start: "2024-01-01T00:00:00Z" }] } ] } diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/patterns.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/patterns.graphql index 3ebd02d28be..101d26e8edb 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/patterns.graphql +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/patterns.graphql @@ -38,6 +38,7 @@ } canceledTrips( serviceDateRanges: [{ start: "2024-08-01", end: "2024-09-01" }] + runningTimeRanges: [{ start: "2024-01-01T00:00:00Z" }] ) { serviceDate realTimeTripState { diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql index b2b238be98f..ed5acd10101 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql @@ -23,6 +23,9 @@ } canceledCalls( serviceDateRanges: [{ start: "2024-08-08", end: "2024-08-10" }] + timeRanges: [ + { start: "2024-08-08T00:00:00Z", end: "2024-08-11T00:00:00Z" } + ] arrivalDeparture: EITHER ) { tripOnServiceDate { diff --git a/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/lund-station-sweden.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/lund-station-sweden.osm.pbf similarity index 100% rename from application/src/test/resources/org/opentripplanner/graph_builder/module/osm/lund-station-sweden.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/lund-station-sweden.osm.pbf diff --git a/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/stopareas.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/stopareas.pbf similarity index 100% rename from application/src/test/resources/org/opentripplanner/graph_builder/module/osm/stopareas.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/stopareas.pbf diff --git a/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/wendlingen-bahnhof.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/wendlingen-bahnhof.osm.pbf similarity index 100% rename from application/src/test/resources/org/opentripplanner/graph_builder/module/osm/wendlingen-bahnhof.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/internal/walkablearea/wendlingen-bahnhof.osm.pbf diff --git a/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/brenner-invalid-relation-reference.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/storage/brenner-invalid-relation-reference.osm.pbf similarity index 100% rename from application/src/test/resources/org/opentripplanner/graph_builder/module/osm/brenner-invalid-relation-reference.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/storage/brenner-invalid-relation-reference.osm.pbf diff --git a/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/ehningen-minimal.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/storage/ehningen-minimal.osm.pbf similarity index 100% rename from application/src/test/resources/org/opentripplanner/graph_builder/module/osm/ehningen-minimal.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/storage/ehningen-minimal.osm.pbf diff --git a/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/storage/map.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/storage/map.osm.pbf new file mode 100644 index 00000000000..d034b04284c Binary files /dev/null and b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/storage/map.osm.pbf differ diff --git a/application/src/test/resources/standalone/config/build-config.json b/application/src/test/resources/standalone/config/build-config.json index bc7f66e3ac2..a2b67074e80 100644 --- a/application/src/test/resources/standalone/config/build-config.json +++ b/application/src/test/resources/standalone/config/build-config.json @@ -19,6 +19,7 @@ "osmTagMapping": "norway" } ], + "elevatorRefTags": [{ "tagGroup": ["manufacturer", "ref"] }], "demDefaults": { "elevationUnitMultiplier": 1.0 }, diff --git a/astar/pom.xml b/astar/pom.xml index 48c012b999e..ae1932c24bc 100644 --- a/astar/pom.xml +++ b/astar/pom.xml @@ -15,8 +15,8 @@ - com.hubspot.maven.plugins - prettier-maven-plugin + com.diffplug.spotless + spotless-maven-plugin diff --git a/astar/src/main/java/org/opentripplanner/astar/strategy/ComposingSkipEdgeStrategy.java b/astar/src/main/java/org/opentripplanner/astar/strategy/ComposingSkipEdgeStrategy.java index 326a2511ec6..2fa0a33dbd6 100644 --- a/astar/src/main/java/org/opentripplanner/astar/strategy/ComposingSkipEdgeStrategy.java +++ b/astar/src/main/java/org/opentripplanner/astar/strategy/ComposingSkipEdgeStrategy.java @@ -12,7 +12,9 @@ public record ComposingSkipEdgeStrategy< State extends AStarState, Edge extends AStarEdge ->(SkipEdgeStrategy... strategies) implements SkipEdgeStrategy { +>( + SkipEdgeStrategy... strategies +) implements SkipEdgeStrategy { @Override public boolean shouldSkipEdge(State current, Edge edge) { for (var strategy : strategies) { diff --git a/astar/src/main/java/org/opentripplanner/astar/strategy/DurationSkipEdgeStrategy.java b/astar/src/main/java/org/opentripplanner/astar/strategy/DurationSkipEdgeStrategy.java index 29094349ecf..b8f2a392f64 100644 --- a/astar/src/main/java/org/opentripplanner/astar/strategy/DurationSkipEdgeStrategy.java +++ b/astar/src/main/java/org/opentripplanner/astar/strategy/DurationSkipEdgeStrategy.java @@ -13,8 +13,7 @@ public class DurationSkipEdgeStrategy< State extends AStarState, Edge extends AStarEdge -> - implements SkipEdgeStrategy { +> implements SkipEdgeStrategy { private final double durationInSeconds; diff --git a/astar/src/main/java/org/opentripplanner/astar/strategy/DurationTerminationStrategy.java b/astar/src/main/java/org/opentripplanner/astar/strategy/DurationTerminationStrategy.java index 2d16ff9e244..03cf2796847 100644 --- a/astar/src/main/java/org/opentripplanner/astar/strategy/DurationTerminationStrategy.java +++ b/astar/src/main/java/org/opentripplanner/astar/strategy/DurationTerminationStrategy.java @@ -8,8 +8,8 @@ * This termination strategy is used to terminate an a-star search after a fixed duration * has elapsed. */ -public class DurationTerminationStrategy> - implements SearchTerminationStrategy { +public class DurationTerminationStrategy> implements + SearchTerminationStrategy { private final double maxDuration_s; diff --git a/astar/src/main/java/org/opentripplanner/astar/strategy/MaxCountTerminationStrategy.java b/astar/src/main/java/org/opentripplanner/astar/strategy/MaxCountTerminationStrategy.java index 66c5496c923..16afcacea9b 100644 --- a/astar/src/main/java/org/opentripplanner/astar/strategy/MaxCountTerminationStrategy.java +++ b/astar/src/main/java/org/opentripplanner/astar/strategy/MaxCountTerminationStrategy.java @@ -9,8 +9,8 @@ * some criteria has been found. For example it can be used to limit a search to a maximum number of * stops. */ -public class MaxCountTerminationStrategy> - implements SearchTerminationStrategy { +public class MaxCountTerminationStrategy> implements + SearchTerminationStrategy { private final int maxCount; private final Predicate shouldIncreaseCount; diff --git a/astar/src/main/java/org/opentripplanner/astar/strategy/NoopStatisticsCallback.java b/astar/src/main/java/org/opentripplanner/astar/strategy/NoopStatisticsCallback.java index 52e2f4540c0..c70cb3c3175 100644 --- a/astar/src/main/java/org/opentripplanner/astar/strategy/NoopStatisticsCallback.java +++ b/astar/src/main/java/org/opentripplanner/astar/strategy/NoopStatisticsCallback.java @@ -7,8 +7,8 @@ /** * A statistics callback that does nothing. */ -public class NoopStatisticsCallback> - implements StatisticsCallback { +public class NoopStatisticsCallback> implements + StatisticsCallback { @Override public void searchStarted() {} diff --git a/astar/src/test/java/org/opentripplanner/astar/model/BinHeapTest.java b/astar/src/test/java/org/opentripplanner/astar/model/BinHeapTest.java index ed0dfb6dc3b..24147283bb7 100644 --- a/astar/src/test/java/org/opentripplanner/astar/model/BinHeapTest.java +++ b/astar/src/test/java/org/opentripplanner/astar/model/BinHeapTest.java @@ -109,7 +109,7 @@ public void testRekey() throws InterruptedException { // fill both keys and values with random numbers for (int i = 0; i < N; i++) { - keys.add(i, (Math.random() * 10000)); + keys.add(i, Math.random() * 10000); vals.add(i, (N - i) * 3); } diff --git a/checkstyle.xml b/checkstyle.xml index 868c491d5ad..dbf20b6e524 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -20,7 +20,6 @@ - diff --git a/doc/dev/decisionrecords/Codestyle.md b/doc/dev/decisionrecords/Codestyle.md index 0c39e8c4181..e1427e9d212 100644 --- a/doc/dev/decisionrecords/Codestyle.md +++ b/doc/dev/decisionrecords/Codestyle.md @@ -3,9 +3,16 @@ ## Java The OpenTripPlanner Java code style is revised in OTP v2.2. We use the -[Prettier Java](https://github.com/jhipster/prettier-java) as is. Maven is set up to run -`prettier-maven-plugin`. A check is run in the CI build, which fails the build preventing merging a -PR if the code style is incorrect. +[Prettier Java](https://github.com/jhipster/prettier-java) as is. Maven is set up to run Prettier +through the [Spotless](https://github.com/diffplug/spotless) Maven plugin. A check is run in the CI +build, which fails the build preventing merging a PR if the code style is incorrect. + +Note! Spotless runs Prettier with Node, so `node` and `npm` must be available on the `PATH`. The +Prettier and Prettier Java versions, as well as the formatting options, are configured in the root +`pom.xml` (`prettier.version`, `prettier.java.version` and the Spotless plugin configuration). + +In addition to running Prettier, Spotless removes unused imports from Java files before formatting +them. Imports that are only referenced from Javadoc (for example `{@link Foo}`) are kept. Additionally since OTP v2.9, we are using Checkstyle to check for code style issues with a Maven plugin. There is also a checkstyle plugin for IntelliJ IDEA which can be used to spot and fix @@ -21,8 +28,10 @@ configured it to run by default as part of our Maven build. We also have OpenRew maven to fix some issues automatically, but it is not run by default as it takes a bit longer to run. -Checkstyle will check for code style issues in the Maven "validate" phase, which runs before the -test, package, and install phases. So checkstyle will happen for example when you run: +Checkstyle will check for code style issues in the Maven "process-sources" phase, which runs after +the "validate" phase used by Spotless (so that Spotless can auto-fix issues like unused imports +first) and before the test, package, and install phases. So checkstyle will happen for example when +you run: ```shell % mvn test @@ -46,7 +55,7 @@ OpenRewrite can be used to fix some of the checkstyle issues automatically. The runs OpenRewrite and Prettier, but not checkstyle: ```shell -% mvn rewrite:run prettier:write -P rewrite +% mvn rewrite:run spotless:apply -P rewrite ``` ### How to Run Prettier @@ -66,7 +75,7 @@ test, package, and install phases. So formatting will happen for example when yo You can manually run _only_ the formatting process with: ```shell -% mvn prettier:write +% mvn spotless:apply ``` To skip the Prettier formating, use the profile `prettierSkip`: @@ -95,15 +104,15 @@ Code Style_. Then select **Project** in the \_Scheme drop down. #### Run Prettier Maven Plugin as an External Tool in IntelliJ -You can run the Prettier Maven plugin as an external tool in IntelliJ. Set it up as an -`External tool` and assign a keyboard shortcut to the tool execution. +You can run Spotless as an external tool in IntelliJ. Set it up as an `External tool` and assign a +keyboard shortcut to the tool execution. ![External Tool Dialog](../images/ExternalToolDialog.png) ```text Name: Prettier Format Current File Program: mvn -Arguments: prettier:write -Dprettier.inputGlobs=$FilePathRelativeToProjectRoot$ +Arguments: spotless:apply -DspotlessFiles=$FilePathRelativeToProjectRoot$ Working Directory: $ProjectFileDir$ ``` @@ -133,7 +142,7 @@ Name: Format files with Prettier File Type: Java Scope: Project Files Program: mvn -Arguments: prettier:write -Dprettier.inputGlobs=$FilePathRelativeToProjectRoot$ +Arguments: spotless:apply -DspotlessFiles=$FilePathRelativeToProjectRoot$ Working Directory: $ProjectFileDir$ ``` diff --git a/doc/dev/decisionrecords/NamingConventions.md b/doc/dev/decisionrecords/NamingConventions.md index 4661ce46357..6a2245365c4 100644 --- a/doc/dev/decisionrecords/NamingConventions.md +++ b/doc/dev/decisionrecords/NamingConventions.md @@ -37,24 +37,24 @@ be `org.opentripplanner...`. Here is a list of common prefixes used and what to expect. -| Good method prefixes | Description | -| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -| `stop() : Stop` | Field accessor, equivalent to `getStop` as in the Java Bean standard. | -| `getStop(ID id) : Stop` | Get Stop by ID; throws exception if not found. | -| `getStops(Collection id) : List/Collection` | Get _all_ Stops by set of IDs; throws exception if not found. | -| `findStop(Criteria criteria) : Optional` | Find one or zero stops; return `Optional`. | -| `findStops(Criteria criteria) : List/Stream` | Find 0, 1, or many stops; return a Collection or Stream (List is preferred). | -| `listStops() : List/Stream` | List ALL stops in context; return a Collection or Stream (List is preferred). | -| `initStop(Stop stop) : void` | Set property _once_; a second call throws an exception. | -| `createStop(String name, ...) : Stop` | Factory methods for creating objects should start with `create` prefix. | -| | See (Builder Conventions)[RecordsPOJOsBuilders.md#builder-conventions] for creating objects with builders. | -| `addStop(Stop stop) : void/Builder` | Add a Stop to a collection of Stops. | -| `addStops(Collection stops) : void/Builder` | Add set of Stops to existing set. | -| `withBike(Consumer body) : Builder` | For nested builders, use lambdas. | -| `withStop(Stop stop) : Builder` | Set Stop in builder, replacing existing value; return `this` builder. | -| `of(FeedScopedId id) : Builder` | Create new builder instance from `Stop` class. | -| `copyOf() : Builder` | Initialize a new builder instance from `Stop` instance with identical values. | -| `build() : Stop` | Finish building stop with a builder. | +| Good method prefixes | Description | +| ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | +| `stop() : Stop` | Field accessor, equivalent to `getStop` as in the Java Bean standard. | +| `getStop(ID id) : Stop` | Get Stop by ID; throws exception if not found. | +| `getStops(Collection id) : Collection/Iterable/Stream` | Get _all_ Stops by set of IDs; throws exception if not found. | +| `findStop(Criteria criteria) : Optional` | Find one or zero stops; return `Optional`. | +| `findStops(Criteria criteria) : Collection/Iterable/Stream` | Find 0, 1, or many stops; return a Collection, Iterable or Stream (List is preferred). | +| `listStops() : Collection/Iterable/Stream` | List ALL stops in context; return a Collection, Iterable or Stream (List is preferred). | +| `initStop(Stop stop) : void` | Set property _once_; a second call throws an exception. | +| `createStop(String name, ...) : Stop` | Factory methods for creating objects should start with `create` prefix. | +| | See (Builder Conventions)[RecordsPOJOsBuilders.md#builder-conventions] for creating objects with builders. | +| `addStop(Stop stop) : void/Builder` | Add a Stop to a collection of Stops. | +| `addStops(Collection stops) : void/Builder` | Add set of Stops to existing set. | +| `withBike(Consumer body) : Builder` | For nested builders, use lambdas. | +| `withStop(Stop stop) : Builder` | Set Stop in builder, replacing existing value; return `this` builder. | +| `of(FeedScopedId id) : Builder` | Create new builder instance from `Stop` class. | +| `copyOf() : Builder` | Initialize a new builder instance from `Stop` instance with identical values. | +| `build() : Stop` | Finish building stop with a builder. | These prefixes are also "allowed" but not preferred; they have some kind of negative "force" to them. diff --git a/doc/user/BuildConfiguration.md b/doc/user/BuildConfiguration.md index 056b3ff3802..0359c361977 100644 --- a/doc/user/BuildConfiguration.md +++ b/doc/user/BuildConfiguration.md @@ -57,6 +57,8 @@ Sections follow that describe particular settings in more depth. | demDefaults | `object` | Default properties for DEM extracts. | *Optional* | | 2.3 | |    [elevationUnitMultiplier](#demDefaults_elevationUnitMultiplier) | `double` | Specify a multiplier to convert elevation units from source to meters. | *Optional* | `1.0` | 2.3 | | [elevationBucket](#elevationBucket) | `object` | Used to download NED elevation tiles from the given AWS S3 bucket. | *Optional* | | na | +| [elevatorRefTags](#elevatorRefTags) | `object[]` | Groups of OSM tags whose values are combined into an elevator id. | *Optional* | | 2.10 | +|       [tagGroup](#elevatorRefTags_0_tagGroup) | `string[]` | The ordered OSM tag keys whose values are combined into one id. | *Optional* | | 2.10 | | [emission](sandbox/Emission.md) | `object` | Emissions configuration. | *Optional* | | 2.5 | | empiricalDelay | `object` | Empirical delay configuration. | *Optional* | | 2.9 | | [fares](sandbox/Fares.md) | `object` | Fare configuration. | *Optional* | | 2.0 | @@ -100,12 +102,12 @@ Sections follow that describe particular settings in more depth. |       [bikesAllowedStopMaxTransferDuration](#tpfm_BIKE_bikesAllowedStopMaxTransferDuration) | `duration` | This is used for specifying a `maxTransferDuration` value to use with transfers between stops which are visited by trips that allow bikes. | *Optional* | | 2.9 | |       [carsAllowedStopMaxTransferDuration](#tpfm_BIKE_carsAllowedStopMaxTransferDuration) | `duration` | This is used for specifying a `maxTransferDuration` value to use with transfers between stops which are visited by trips that allow cars. | *Optional* | | 2.7 | |       [disableDefaultTransfers](#tpfm_BIKE_disableDefaultTransfers) | `boolean` | This disables default transfer calculations. | *Optional* | `false` | 2.7 | -|       maxTransferDuration | `duration` | This overwrites the default `maxTransferDuration` for the given mode. | *Optional* | | 2.7 | +|       [maxTransferDuration](#tpfm_BIKE_maxTransferDuration) | `duration` | This overwrites the default `maxTransferDuration` for the given mode. | *Optional* | | 2.7 | |    CAR | `object` | NA | *Optional* | | 2.7 | |       [bikesAllowedStopMaxTransferDuration](#tpfm_CAR_bikesAllowedStopMaxTransferDuration) | `duration` | This is used for specifying a `maxTransferDuration` value to use with transfers between stops which are visited by trips that allow bikes. | *Optional* | | 2.9 | |       [carsAllowedStopMaxTransferDuration](#tpfm_CAR_carsAllowedStopMaxTransferDuration) | `duration` | This is used for specifying a `maxTransferDuration` value to use with transfers between stops which are visited by trips that allow cars. | *Optional* | | 2.7 | |       [disableDefaultTransfers](#tpfm_CAR_disableDefaultTransfers) | `boolean` | This disables default transfer calculations. | *Optional* | `false` | 2.7 | -|       maxTransferDuration | `duration` | This overwrites the default `maxTransferDuration` for the given mode. | *Optional* | | 2.7 | +|       [maxTransferDuration](#tpfm_CAR_maxTransferDuration) | `duration` | This overwrites the default `maxTransferDuration` for the given mode. | *Optional* | | 2.7 | | [transferRequests](RouteRequest.md) | `object[]` | Routing requests to use for pre-calculating stop-to-stop transfers. | *Optional* | | 2.1 | | [transitFeeds](#transitFeeds) | `object[]` | Scan for transit data files | *Optional* | | 2.2 | |    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.2 | @@ -780,6 +782,26 @@ for the next graph build operation. You should add the `--cache ` com to specify your NED tile cache location. +

elevatorRefTags

+ +**Since version:** `2.10` ∙ **Type:** `object[]` ∙ **Cardinality:** `Optional` +**Path:** / + +Groups of OSM tags whose values are combined into an elevator id. + +Each group is a list of one or more OSM tag keys. If every tag in a group is present +on an elevator node/way, their values are joined with ':' (in the given order) into +one id. A group with a single tag key produces a plain id. If any tag in a group is +missing, that group produces no id. If more than one group is configured, the first +one (in the given order) that produces an id is used as the elevator's id. + +

tagGroup

+ +**Since version:** `2.10` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /elevatorRefTags/[0] + +The ordered OSM tag keys whose values are combined into one id. +

discardMinTransferTimes

**Since version:** `2.3` ∙ **Type:** `boolean` ∙ **Cardinality:** `Optional` ∙ **Default value:** `false` @@ -1048,19 +1070,17 @@ To configure mode-specific parameters, the modes should also be used in the `tra **Since version:** `2.9` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` **Path:** /transferParametersForMode/BIKE -This is used for specifying a `maxTransferDuration` value to use with transfers between stops which are visited by trips that allow bikes. +This is used for specifying a `maxTransferDuration` value to use with transfers between +stops which are visited by trips that allow bikes. -This parameter configures additional transfers to be calculated for the specified mode only between stops that have trips with bikes. -The transfers are calculated for the mode in a range based on the given duration. -By default, these transfers are not calculated unless specified for a mode with this field. -When compared to walking, using a bike can cover larger distances within the same duration specified in the `maxTransferDuration` field. -This can lead to large amounts of transfers calculated between stops that do not require bike transfers between them. -This in turn can lead to a large increase in memory for the stored graph, depending on the data used in the graph. +Configures a separate `maxTransferDuration` for the given mode, used only for transfers +between stops visited by trips that allow bikes, instead of the given mode's +`maxTransferDuration`. -For bikes, using this parameter in conjunction with `disableDefaultTransfers` allows calculating transfers only between stops -which have trips which allow carrying bikes. This avoids storing and calculating transfers which are never used so the transit search -can be faster compared to the default transfers. +In combination with the mode's `maxTransferDuration` you can include transfers for bikes +between all stops in a smaller radius, and use a larger radius for transfers between +stops where bikes are explicit allowed.

carsAllowedStopMaxTransferDuration

@@ -1068,24 +1088,18 @@ can be faster compared to the default transfers. **Since version:** `2.7` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` **Path:** /transferParametersForMode/BIKE -This is used for specifying a `maxTransferDuration` value to use with transfers between stops which are visited by trips that allow cars. +This is used for specifying a `maxTransferDuration` value to use with transfers between +stops which are visited by trips that allow cars. -This parameter configures additional transfers to be calculated for the specified mode only between stops that have trips with cars. -The transfers are calculated for the mode in a range based on the given duration. -By default, these transfers are not calculated unless specified for a mode with this field. -Calculating transfers only between stops that have trips with cars can be useful with car ferries, for example. -Using transit with cars can only occur between certain stops. -These kinds of stops require support for loading cars into ferries, for example. -The default transfers are calculated based on a configurable range (configurable by using the `maxTransferDuration` field) -which limits transfers from stops to only be calculated to other stops that are in range. -When compared to walking, using a car can cover larger distances within the same duration specified in the `maxTransferDuration` field. -This can lead to large amounts of transfers calculated between stops that do not require car transfers between them. -This in turn can lead to a large increase in memory for the stored graph, depending on the data used in the graph. +Configures a separate `maxTransferDuration` for the given mode, used only for transfers +between stops visited by trips that allow cars (e.g. car ferries), instead of the given +mode's `maxTransferDuration`. -For cars, using this parameter in conjunction with `disableDefaultTransfers` allows calculating transfers only between relevant stops. -For bikes, using this parameter can enable transfers between ferry stops that would normally not be in range. -In Finland this is useful for bike routes that use ferries near the Turku archipelago, for example. +This can also be configured for other modes. For example, for bikes, this can enable +transfers between ferry stops that would otherwise be out of range, since car ferries +usually also allow bikes. This is useful for bike routes using ferries near the Turku +archipelago in Finland, for example.

disableDefaultTransfers

@@ -1095,12 +1109,29 @@ In Finland this is useful for bike routes that use ferries near the Turku archip This disables default transfer calculations. -The default transfers are calculated based on a configurable range (configurable by using the `maxTransferDuration` field) -which limits transfers from stops to only be calculated to other stops that are in range. -This parameter disables these transfers. -A motivation to disable default transfers could be related to using the `carsAllowedStopMaxTransferDuration` field which only -calculates transfers between stops that have trips with cars, or `bikesAllowedStopMaxTransferDuration` field for bikes. -For example, when using the `carsAllowedStopMaxTransferDuration` field with cars, the default transfers can be redundant. +By default, transfers are calculated between all stop pairs within the given mode's +`maxTransferDuration`. This parameter disables that default calculation for the mode. + +This is used together with `carsAllowedStopMaxTransferDuration` or +`bikesAllowedStopMaxTransferDuration`, so that only the restricted, relevant transfers are +calculated. + + +

maxTransferDuration

+ +**Since version:** `2.7` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` +**Path:** /transferParametersForMode/BIKE + +This overwrites the default `maxTransferDuration` for the given mode. + +A car or a bike can cover a much larger distance than walking within the same duration. +Reusing this value would reduce the search radius, calculating fewer transfers and +decreases the graph memory usage. + +If it isn't known which stops actually allow cars/bikes, combine a lower value here with +`carsAllowedStopMaxTransferDuration` or `bikesAllowedStopMaxTransferDuration` as a +compromise: this bounds memory usage for stops in general, while the allowed-stop field +still supplies a longer range for the stops it is known to be needed for.

bikesAllowedStopMaxTransferDuration

@@ -1108,19 +1139,17 @@ For example, when using the `carsAllowedStopMaxTransferDuration` field with cars **Since version:** `2.9` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` **Path:** /transferParametersForMode/CAR -This is used for specifying a `maxTransferDuration` value to use with transfers between stops which are visited by trips that allow bikes. +This is used for specifying a `maxTransferDuration` value to use with transfers between +stops which are visited by trips that allow bikes. -This parameter configures additional transfers to be calculated for the specified mode only between stops that have trips with bikes. -The transfers are calculated for the mode in a range based on the given duration. -By default, these transfers are not calculated unless specified for a mode with this field. -When compared to walking, using a bike can cover larger distances within the same duration specified in the `maxTransferDuration` field. -This can lead to large amounts of transfers calculated between stops that do not require bike transfers between them. -This in turn can lead to a large increase in memory for the stored graph, depending on the data used in the graph. +Configures a separate `maxTransferDuration` for the given mode, used only for transfers +between stops visited by trips that allow bikes, instead of the given mode's +`maxTransferDuration`. -For bikes, using this parameter in conjunction with `disableDefaultTransfers` allows calculating transfers only between stops -which have trips which allow carrying bikes. This avoids storing and calculating transfers which are never used so the transit search -can be faster compared to the default transfers. +In combination with the mode's `maxTransferDuration` you can include transfers for bikes +between all stops in a smaller radius, and use a larger radius for transfers between +stops where bikes are explicit allowed.

carsAllowedStopMaxTransferDuration

@@ -1128,24 +1157,18 @@ can be faster compared to the default transfers. **Since version:** `2.7` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` **Path:** /transferParametersForMode/CAR -This is used for specifying a `maxTransferDuration` value to use with transfers between stops which are visited by trips that allow cars. +This is used for specifying a `maxTransferDuration` value to use with transfers between +stops which are visited by trips that allow cars. -This parameter configures additional transfers to be calculated for the specified mode only between stops that have trips with cars. -The transfers are calculated for the mode in a range based on the given duration. -By default, these transfers are not calculated unless specified for a mode with this field. -Calculating transfers only between stops that have trips with cars can be useful with car ferries, for example. -Using transit with cars can only occur between certain stops. -These kinds of stops require support for loading cars into ferries, for example. -The default transfers are calculated based on a configurable range (configurable by using the `maxTransferDuration` field) -which limits transfers from stops to only be calculated to other stops that are in range. -When compared to walking, using a car can cover larger distances within the same duration specified in the `maxTransferDuration` field. -This can lead to large amounts of transfers calculated between stops that do not require car transfers between them. -This in turn can lead to a large increase in memory for the stored graph, depending on the data used in the graph. +Configures a separate `maxTransferDuration` for the given mode, used only for transfers +between stops visited by trips that allow cars (e.g. car ferries), instead of the given +mode's `maxTransferDuration`. -For cars, using this parameter in conjunction with `disableDefaultTransfers` allows calculating transfers only between relevant stops. -For bikes, using this parameter can enable transfers between ferry stops that would normally not be in range. -In Finland this is useful for bike routes that use ferries near the Turku archipelago, for example. +This can also be configured for other modes. For example, for bikes, this can enable +transfers between ferry stops that would otherwise be out of range, since car ferries +usually also allow bikes. This is useful for bike routes using ferries near the Turku +archipelago in Finland, for example.

disableDefaultTransfers

@@ -1155,12 +1178,29 @@ In Finland this is useful for bike routes that use ferries near the Turku archip This disables default transfer calculations. -The default transfers are calculated based on a configurable range (configurable by using the `maxTransferDuration` field) -which limits transfers from stops to only be calculated to other stops that are in range. -This parameter disables these transfers. -A motivation to disable default transfers could be related to using the `carsAllowedStopMaxTransferDuration` field which only -calculates transfers between stops that have trips with cars, or `bikesAllowedStopMaxTransferDuration` field for bikes. -For example, when using the `carsAllowedStopMaxTransferDuration` field with cars, the default transfers can be redundant. +By default, transfers are calculated between all stop pairs within the given mode's +`maxTransferDuration`. This parameter disables that default calculation for the mode. + +This is used together with `carsAllowedStopMaxTransferDuration` or +`bikesAllowedStopMaxTransferDuration`, so that only the restricted, relevant transfers are +calculated. + + +

maxTransferDuration

+ +**Since version:** `2.7` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` +**Path:** /transferParametersForMode/CAR + +This overwrites the default `maxTransferDuration` for the given mode. + +A car or a bike can cover a much larger distance than walking within the same duration. +Reusing this value would reduce the search radius, calculating fewer transfers and +decreases the graph memory usage. + +If it isn't known which stops actually allow cars/bikes, combine a lower value here with +`carsAllowedStopMaxTransferDuration` or `bikesAllowedStopMaxTransferDuration` as a +compromise: this bounds memory usage for stops in general, while the allowed-stop field +still supplies a longer range for the stops it is known to be needed for.

transitFeeds

@@ -1330,6 +1370,14 @@ the centroid. "osmTagMapping" : "norway" } ], + "elevatorRefTags" : [ + { + "tagGroup" : [ + "manufacturer", + "ref" + ] + } + ], "demDefaults" : { "elevationUnitMultiplier" : 1.0 }, diff --git a/doc/user/Changelog.md b/doc/user/Changelog.md index 68692037255..33990a114a5 100644 --- a/doc/user/Changelog.md +++ b/doc/user/Changelog.md @@ -118,6 +118,11 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Frequency-based vehicle position matching [#7927](https://github.com/opentripplanner/OpenTripPlanner/pull/7927) - Move per-network GBFS configuration into a shared gbfs section of otp-config.json [#7886](https://github.com/opentripplanner/OpenTripPlanner/pull/7886) - Compact node storage to reduce graph build memory [#7925](https://github.com/opentripplanner/OpenTripPlanner/pull/7925) +- Add `runningTimeRanges` filter to canceled trips/calls queries in the GTFS API [#7899](https://github.com/opentripplanner/OpenTripPlanner/pull/7899) +- Change APIs to properly support alerts with multiple active periods [#7926](https://github.com/opentripplanner/OpenTripPlanner/pull/7926) +- Fix GTFS GraphQL API's stop call's real-time estimated times [#7953](https://github.com/opentripplanner/OpenTripPlanner/pull/7953) +- Remove street notes feature [#7959](https://github.com/opentripplanner/OpenTripPlanner/pull/7959) +- Add alertConnection query to the GTFS GraphQL API [#7924](https://github.com/opentripplanner/OpenTripPlanner/pull/7924) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.9.0 (2026-03-18) diff --git a/doc/user/requirements.txt b/doc/user/requirements.txt index 469ffa0b2cf..d4f3a6fe3a1 100644 --- a/doc/user/requirements.txt +++ b/doc/user/requirements.txt @@ -1,4 +1,4 @@ mkdocs==1.6.1 -mkdocs-material==9.7.6 +mkdocs-material==9.7.7 mike==2.2.0 mkdocs-no-sitemap-plugin==0.0.1 diff --git a/domain-core/pom.xml b/domain-core/pom.xml index b23c0158297..694abb9b924 100644 --- a/domain-core/pom.xml +++ b/domain-core/pom.xml @@ -15,8 +15,8 @@ - com.hubspot.maven.plugins - prettier-maven-plugin + com.diffplug.spotless + spotless-maven-plugin diff --git a/domain-core/src/main/java/org/opentripplanner/core/model/basic/Cost.java b/domain-core/src/main/java/org/opentripplanner/core/model/basic/Cost.java index d9b9cb341fa..2908c696bbf 100644 --- a/domain-core/src/main/java/org/opentripplanner/core/model/basic/Cost.java +++ b/domain-core/src/main/java/org/opentripplanner/core/model/basic/Cost.java @@ -124,7 +124,7 @@ public boolean equals(Object o) { if (o == null) { return false; } - return (o instanceof Cost c) ? value == c.value : false; + return o instanceof Cost c ? value == c.value : false; } @Override diff --git a/domain-core/src/main/java/org/opentripplanner/core/model/i18n/NonLocalizedString.java b/domain-core/src/main/java/org/opentripplanner/core/model/i18n/NonLocalizedString.java index 301248d1df9..9a0d9b22c38 100644 --- a/domain-core/src/main/java/org/opentripplanner/core/model/i18n/NonLocalizedString.java +++ b/domain-core/src/main/java/org/opentripplanner/core/model/i18n/NonLocalizedString.java @@ -83,7 +83,7 @@ public int hashCode() { @Override public boolean equals(Object other) { - return (other instanceof NonLocalizedString that && this.name.equals(that.name)); + return other instanceof NonLocalizedString that && this.name.equals(that.name); } @Override diff --git a/domain-core/src/main/java/org/opentripplanner/core/model/i18n/TranslatedString.java b/domain-core/src/main/java/org/opentripplanner/core/model/i18n/TranslatedString.java index 4986eb9eddd..7c044f27729 100644 --- a/domain-core/src/main/java/org/opentripplanner/core/model/i18n/TranslatedString.java +++ b/domain-core/src/main/java/org/opentripplanner/core/model/i18n/TranslatedString.java @@ -14,7 +14,7 @@ /** * This is for translated strings for which translations are read from OSM or GTFS alerts. *

- * This can be translated street names, GTFS alerts and notes. + * This can be translated street names, GTFS alerts etc. * * @author Hannes Junnila */ @@ -146,7 +146,7 @@ public int hashCode() { @Override public boolean equals(Object other) { return ( - (other instanceof TranslatedString) && + other instanceof TranslatedString && this.translations.equals(((TranslatedString) other).translations) ); } diff --git a/domain-core/src/main/java/org/opentripplanner/core/model/time/LocalDateRange.java b/domain-core/src/main/java/org/opentripplanner/core/model/time/LocalDateRange.java index 46d4db5cb3e..bd97234d632 100644 --- a/domain-core/src/main/java/org/opentripplanner/core/model/time/LocalDateRange.java +++ b/domain-core/src/main/java/org/opentripplanner/core/model/time/LocalDateRange.java @@ -235,6 +235,6 @@ public boolean equals(Object o) { public String toString() { var start = ServiceDateUtils.toString(inclusiveStart); var end = ServiceDateUtils.toString(exclusiveEnd); - return ("[" + start + ", " + end + ")"); + return "[" + start + ", " + end + ")"; } } diff --git a/domain-core/src/main/java/org/opentripplanner/core/model/time/TimePeriod.java b/domain-core/src/main/java/org/opentripplanner/core/model/time/TimePeriod.java index 39de8538dca..be644bf7d2a 100644 --- a/domain-core/src/main/java/org/opentripplanner/core/model/time/TimePeriod.java +++ b/domain-core/src/main/java/org/opentripplanner/core/model/time/TimePeriod.java @@ -7,10 +7,10 @@ import org.opentripplanner.utils.tostring.ToStringBuilder; /** - * Represents a half-open period of time {@code [start, end)}. + * Represents a period of time with an inclusive start and an exclusive end {@code [start, end)}. *

- * Both bounds are optional: a {@code null} start means that the period has always been valid, and a - * {@code null} end means that it is valid indefinitely (open-ended). + * Both bounds are optional: a {@code null} start means that the period has always been valid + * (unbounded start), and a {@code null} end means that it is valid indefinitely (unbounded end). */ public final class TimePeriod { @@ -64,25 +64,25 @@ public Optional end() { /** * Returns {@code true} if the period has no defined start, meaning it has always been valid. */ - public boolean hasOpenStart() { + public boolean hasUnboundedStart() { return start == null; } /** * Returns {@code true} if the period has no defined end, meaning it is valid indefinitely. */ - public boolean hasOpenEnd() { + public boolean hasUnboundedEnd() { return end == null; } /** - * Returns {@code true} if this period overlaps the given {@code other} period. Open bounds on - * either period are treated as extending indefinitely in that direction. + * Returns {@code true} if this period overlaps the given {@code other} period. Unbounded bounds + * on either period are treated as extending indefinitely in that direction. */ public boolean overlaps(TimePeriod other) { return ( - (hasOpenStart() || other.hasOpenEnd() || start.isBefore(other.end)) && - (hasOpenEnd() || other.hasOpenStart() || other.start.isBefore(end)) + (hasUnboundedStart() || other.hasUnboundedEnd() || start.isBefore(other.end)) && + (hasUnboundedEnd() || other.hasUnboundedStart() || other.start.isBefore(end)) ); } @@ -90,7 +90,10 @@ public boolean overlaps(TimePeriod other) { * Returns {@code true} if the {@code instant} is within this period. */ public boolean contains(Instant instant) { - return ((hasOpenStart() || !instant.isBefore(start)) && (hasOpenEnd() || end.isAfter(instant))); + return ( + (hasUnboundedStart() || !instant.isBefore(start)) && + (hasUnboundedEnd() || end.isAfter(instant)) + ); } @Override diff --git a/domain-core/src/test/java/org/opentripplanner/core/model/time/TimePeriodTest.java b/domain-core/src/test/java/org/opentripplanner/core/model/time/TimePeriodTest.java index 27967c06c3f..5e923906e8a 100644 --- a/domain-core/src/test/java/org/opentripplanner/core/model/time/TimePeriodTest.java +++ b/domain-core/src/test/java/org/opentripplanner/core/model/time/TimePeriodTest.java @@ -1,9 +1,9 @@ package org.opentripplanner.core.model.time; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.time.Instant; import org.junit.jupiter.api.Test; @@ -18,8 +18,8 @@ void of() { var subject = TimePeriod.of(START, END); assertThat(subject.start()).hasValue(START); assertThat(subject.end()).hasValue(END); - assertFalse(subject.hasOpenStart()); - assertFalse(subject.hasOpenEnd()); + assertFalse(subject.hasUnboundedStart()); + assertFalse(subject.hasUnboundedEnd()); } @Test @@ -27,22 +27,22 @@ void ofUnbounded() { var subject = TimePeriod.ofUnbounded(); assertThat(subject.start()).isEmpty(); assertThat(subject.end()).isEmpty(); - assertTrue(subject.hasOpenStart()); - assertTrue(subject.hasOpenEnd()); + assertTrue(subject.hasUnboundedStart()); + assertTrue(subject.hasUnboundedEnd()); } @Test - void openStart() { + void unboundedStart() { var subject = TimePeriod.of(null, END); - assertTrue(subject.hasOpenStart()); - assertFalse(subject.hasOpenEnd()); + assertTrue(subject.hasUnboundedStart()); + assertFalse(subject.hasUnboundedEnd()); } @Test - void openEnd() { + void unboundedEnd() { var subject = TimePeriod.of(START, null); - assertFalse(subject.hasOpenStart()); - assertTrue(subject.hasOpenEnd()); + assertFalse(subject.hasUnboundedStart()); + assertTrue(subject.hasUnboundedEnd()); } @Test @@ -71,29 +71,29 @@ void overlapsBoundedPeriod() { } @Test - void overlapsOpenStart() { + void overlapsUnboundedStart() { var subject = TimePeriod.of(null, END); assertTrue(subject.overlaps(TimePeriod.of(START.minusSeconds(2000), START.minusSeconds(1000)))); assertFalse(subject.overlaps(TimePeriod.of(END.plusSeconds(100), END.plusSeconds(200)))); } @Test - void overlapsOpenEnd() { + void overlapsUnboundedEnd() { var subject = TimePeriod.of(START, null); assertFalse(subject.overlaps(TimePeriod.of(START.minusSeconds(200), START.minusSeconds(100)))); assertTrue(subject.overlaps(TimePeriod.of(END.plusSeconds(100), END.plusSeconds(200)))); } @Test - void overlapsOpenBoundsOnOtherPeriod() { + void overlapsUnboundedBoundsOnOtherPeriod() { var subject = TimePeriod.of(START, END); - // other period is open-ended, starting before this period ends + // other period has an unbounded end, starting before this period ends assertTrue(subject.overlaps(TimePeriod.of(END.minusSeconds(100), null))); - // other period is open-ended, starting exactly at this period's end - exclusive + // other period has an unbounded end, starting exactly at this period's end - exclusive assertFalse(subject.overlaps(TimePeriod.of(END, null))); - // other period has an open start, ending after this period starts + // other period has an unbounded start, ending after this period starts assertTrue(subject.overlaps(TimePeriod.of(null, START.plusSeconds(1)))); - // other period has an open start, ending exactly at this period's start. Because end + // other period has an unbounded start, ending exactly at this period's start. Because end // is exclusive, there is no overlap assertFalse(subject.overlaps(TimePeriod.of(null, START))); // other period is entirely unbounded @@ -125,10 +125,10 @@ void containsBoundedPeriod() { } @Test - void containsOpenStart() { + void containsUnboundedStart() { var subject = TimePeriod.of(null, END); - // far in the past is contained because the start is open + // far in the past is contained because the start is unbounded assertTrue(subject.contains(Instant.EPOCH)); assertTrue(subject.contains(START)); // exactly at the end - exclusive @@ -137,14 +137,14 @@ void containsOpenStart() { } @Test - void containsOpenEnd() { + void containsUnboundedEnd() { var subject = TimePeriod.of(START, null); // before the start assertFalse(subject.contains(START.minusSeconds(1))); // exactly at the start - inclusive assertTrue(subject.contains(START)); - // far in the future is contained because the end is open + // far in the future is contained because the end is unbounded assertTrue(subject.contains(END.plusSeconds(1_000_000))); } diff --git a/openrewrite.yml b/openrewrite.yml index b9a8479437c..602e010e663 100644 --- a/openrewrite.yml +++ b/openrewrite.yml @@ -8,4 +8,3 @@ recipeList: - org.openrewrite.staticanalysis.EmptyBlock - org.openrewrite.staticanalysis.StringLiteralEquality - org.openrewrite.staticanalysis.RemoveUnusedLocalVariables - - org.openrewrite.java.RemoveUnusedImports diff --git a/otp-shaded/pom.xml b/otp-shaded/pom.xml index b67b3136ffc..807cd6a875d 100644 --- a/otp-shaded/pom.xml +++ b/otp-shaded/pom.xml @@ -117,8 +117,8 @@ --> - com.hubspot.maven.plugins - prettier-maven-plugin + com.diffplug.spotless + spotless-maven-plugin true diff --git a/pom.xml b/pom.xml index 8e7a287a5b4..dd59a1d1b40 100644 --- a/pom.xml +++ b/pom.xml @@ -58,25 +58,25 @@ - 272 + 276 - 34.4 + 34.5 2.60.1 - 2.22.1 + 2.22.2 4.0.9 3.1.12 6.1.2 1.14.1 5.6.0 - 1.6.1 + 1.6.3 10.5.0 - 1.17.0 + 1.17.1 2.0.15.3 5.6.0 4.35.1 2.0.6 - 2.0.18 + 2.0.19 UTF-8 opentripplanner/OpenTripPlanner @@ -85,9 +85,13 @@ --> false - 0.22 - write - false + 3.10.0 + apply + false + + 3.9.6 + 2.10.3 true true @@ -117,25 +121,100 @@ 3.6.2 - com.hubspot.maven.plugins - prettier-maven-plugin - ${plugin.prettier.version} + + com.diffplug.spotless + spotless-maven-plugin + ${plugin.spotless.version} - ${plugin.prettier.skip} - 2.7.7 - - src/main/java/**/*.java - src/test/java/**/*.java - src/test-fixtures/java/**/*.java - src/main/java/**/*.md - + ${plugin.spotless.skip} + + + src/main/java/**/*.java + src/test/java/**/*.java + src/test-fixtures/java/**/*.java + + src/ext/java/**/*.java + src/ext-test/java/**/*.java + + + + **/node_modules/** + + + + cleanthat-javaparser-unnecessaryimport + + + + ${prettier.version} + ${prettier.java.version} + + + prettier-plugin-java + java + 100 + 2 + false + lf + + + + + + + src/main/java/**/*.md + + + **/node_modules/** + + + + ${prettier.version} + + + markdown + always + 100 + + + + + + src/**/*.json + src/test/resources/org/opentripplanner/apis/**/*.graphql + + + **/node_modules/** + src/test/resources/org/opentripplanner/apis/vectortiles/style.json + + + + ${prettier.version} + + + + prettier-format validate - ${plugin.prettier.goal} + ${plugin.spotless.goal} @@ -144,18 +223,38 @@ - com.hubspot.maven.plugins - prettier-maven-plugin + com.diffplug.spotless + spotless-maven-plugin false - - *.md - doc/**/*.md - - !doc/user/**/*.md - + + + + + + *.md + doc/**/*.md + + + **/node_modules/** + + doc/user/**/*.md + + + + ${prettier.version} + + + markdown + always + 100 + + + + @@ -406,7 +505,12 @@ validate - validate + + process-sources check @@ -492,7 +596,7 @@ com.google.cloud libraries-bom - 26.86.0 + 26.88.0 pom import @@ -515,7 +619,7 @@ com.google.guava guava - 33.6.0-jre + 33.7.1-jre @@ -637,7 +741,7 @@ prettierCheck - check + check @@ -653,7 +757,7 @@ - true + true @@ -721,6 +825,30 @@ + + + integrationTests + + + + it + + + + + + integration + + true + + + release diff --git a/raptor/pom.xml b/raptor/pom.xml index 72d30bfbb06..3593cb2c4ef 100644 --- a/raptor/pom.xml +++ b/raptor/pom.xml @@ -15,8 +15,8 @@ - com.hubspot.maven.plugins - prettier-maven-plugin + com.diffplug.spotless + spotless-maven-plugin diff --git a/raptor/src/main/java/org/opentripplanner/raptor/api/model/GeneralizedCostRelaxFunction.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/GeneralizedCostRelaxFunction.java index 432ea20f747..daae2c06dd4 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/api/model/GeneralizedCostRelaxFunction.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/model/GeneralizedCostRelaxFunction.java @@ -63,7 +63,7 @@ public static RelaxFunction of(double ratio) { } public int relax(int value) { - return ((value * normalizedRatio) / RATIO_RESOLUTION) + slack; + return (value * normalizedRatio) / RATIO_RESOLUTION + slack; } @Override diff --git a/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/AbstractViaLocationBuilder.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/AbstractViaLocationBuilder.java index d930e7be42a..3b26851fc67 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/AbstractViaLocationBuilder.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/AbstractViaLocationBuilder.java @@ -3,8 +3,9 @@ import java.util.ArrayList; import java.util.List; -abstract sealed class AbstractViaLocationBuilder - permits ViaVisitLocationBuilder, PassThroughLocationBuilder { +abstract sealed class AbstractViaLocationBuilder permits + ViaVisitLocationBuilder, + PassThroughLocationBuilder { protected final String label; protected final List connections = new ArrayList<>(); diff --git a/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/PassThroughLocationBuilder.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/PassThroughLocationBuilder.java index 931e9d270bb..48a8710cda5 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/PassThroughLocationBuilder.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/PassThroughLocationBuilder.java @@ -3,7 +3,8 @@ import java.util.stream.IntStream; public final class PassThroughLocationBuilder - extends AbstractViaLocationBuilder { + extends AbstractViaLocationBuilder +{ public PassThroughLocationBuilder(String label) { super(label); diff --git a/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/RaptorViaLocation.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/RaptorViaLocation.java index d07f4aa5e48..9a268777cec 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/RaptorViaLocation.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/RaptorViaLocation.java @@ -131,15 +131,13 @@ public String toString(RaptorStopNameResolver stopNameResolver) { if (label != null) { buf.append(label).append(" "); } - buf - .append(connections.size() <= 10 ? ": " : "(10/" + connections.size() + "): ") - .append( - connections - .stream() - .limit(10) - .map(it -> it.toString(stopNameResolver)) - .toList() - ); + buf.append(connections.size() <= 10 ? ": " : "(10/" + connections.size() + "): ").append( + connections + .stream() + .limit(10) + .map(it -> it.toString(stopNameResolver)) + .toList() + ); return buf.append("}").toString(); } diff --git a/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/ViaConnection.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/ViaConnection.java index 4c0964b1521..7eb240f3fe8 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/ViaConnection.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/ViaConnection.java @@ -40,8 +40,8 @@ /// {@code durationInSeconds}. The calculation of `c1` should include the walk time, but not /// the min-wait-time (assuming all connections have the same minimum wait time). public abstract sealed class ViaConnection - permits - RaptorPassThroughViaConnection, RaptorTransferViaConnection, RaptorVisitStopViaConnection { + permits RaptorPassThroughViaConnection, RaptorTransferViaConnection, RaptorVisitStopViaConnection +{ private final int fromStop; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/ViaVisitLocationBuilder.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/ViaVisitLocationBuilder.java index 8e25f2962cd..048d9ed31dc 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/ViaVisitLocationBuilder.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/request/via/ViaVisitLocationBuilder.java @@ -4,7 +4,8 @@ import org.opentripplanner.raptor.spi.RaptorTransfer; public final class ViaVisitLocationBuilder - extends AbstractViaLocationBuilder { + extends AbstractViaLocationBuilder +{ private final int minimumWaitTime; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/extensions/direct/service/DirectTransitSearch.java b/raptor/src/main/java/org/opentripplanner/raptor/extensions/direct/service/DirectTransitSearch.java index fcbb717ceb4..89d148d1da7 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/extensions/direct/service/DirectTransitSearch.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/extensions/direct/service/DirectTransitSearch.java @@ -210,8 +210,8 @@ static int calculateIterationDepartureTime(int accessDuration, int boardTime, in } /// This comparator uses a relax function on the cost to decide if a path dominates another. - private static class DestinationArrivalComparator - implements ParetoComparator> { + private static class DestinationArrivalComparator implements + ParetoComparator> { private final RelaxFunction relaxFunction; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/path/PathBuilderLeg.java b/raptor/src/main/java/org/opentripplanner/raptor/path/PathBuilderLeg.java index 62657073081..736afac625a 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/path/PathBuilderLeg.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/path/PathBuilderLeg.java @@ -578,9 +578,10 @@ private int transitCost( var prevTransit = prevTransitLeg(); var txBeforeLeg = prevTransit == null ? null : prevTransit.constrainedTransferAfterLeg(); - var transferConstraint = txBeforeLeg == null - ? RaptorTransferConstraint.REGULAR_TRANSFER - : txBeforeLeg.getTransferConstraint(); + var transferConstraint = + txBeforeLeg == null + ? RaptorTransferConstraint.REGULAR_TRANSFER + : txBeforeLeg.getTransferConstraint(); boolean firstBoarding = prev != null && prev.isAccessWithoutRides(); int boardCost = costCalculator.boardingCost( diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/ConcurrentCompositeRaptorRouter.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/ConcurrentCompositeRaptorRouter.java index ab6def8fafe..b0a4e2ed39d 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/ConcurrentCompositeRaptorRouter.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/ConcurrentCompositeRaptorRouter.java @@ -16,8 +16,8 @@ * {@link ExecutorService} is provided. * @see CompositeResult for joining results. */ -public class ConcurrentCompositeRaptorRouter - implements RaptorRouter { +public class ConcurrentCompositeRaptorRouter implements + RaptorRouter { private final RaptorRouter mainWorker; private final RaptorRouter alternativeWorker; @@ -74,7 +74,7 @@ public RaptorRouterResult route() { alternativeResultFuture.cancel(true); throw mapInterruptedException.apply(e); } catch (ExecutionException e) { - throw (e.getCause() instanceof RuntimeException re) ? re : new RuntimeException(e); + throw e.getCause() instanceof RuntimeException re ? re : new RuntimeException(e); } } } diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/DefaultRangeRaptorWorker.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/DefaultRangeRaptorWorker.java index 802194af14d..2221513d689 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/DefaultRangeRaptorWorker.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/DefaultRangeRaptorWorker.java @@ -49,8 +49,8 @@ * @param The TripSchedule type defined by the user of the raptor API. */ @SuppressWarnings("Duplicates") -public final class DefaultRangeRaptorWorker - implements RangeRaptorWorker { +public final class DefaultRangeRaptorWorker implements + RangeRaptorWorker { private final RoutingStrategy transitWorker; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/RangeRaptorWorkerComposite.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/RangeRaptorWorkerComposite.java index 76da01f9064..f31c8d44a91 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/RangeRaptorWorkerComposite.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/RangeRaptorWorkerComposite.java @@ -21,8 +21,8 @@ * {@link org.opentripplanner.raptor.rangeraptor.context.SearchContextViaSegments} * for more information. */ -public class RangeRaptorWorkerComposite - implements RangeRaptorWorker { +public class RangeRaptorWorkerComposite implements + RangeRaptorWorker { private final List> children; private final ParetoComparator> comparator; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerPatternRideAdapter.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerPatternRideAdapter.java index 3e2ff7aaf12..8fd296761bb 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerPatternRideAdapter.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerPatternRideAdapter.java @@ -7,7 +7,8 @@ import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; final class DebugHandlerPatternRideAdapter - extends AbstractDebugHandlerAdapter> { + extends AbstractDebugHandlerAdapter> +{ DebugHandlerPatternRideAdapter(DebugRequest debug, WorkerLifeCycle lifeCycle) { super(debug, debug.patternRideDebugListener(), lifeCycle); diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/HeuristicAtStop.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/HeuristicAtStop.java index bac821da856..6ee9a66acde 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/HeuristicAtStop.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/HeuristicAtStop.java @@ -21,10 +21,10 @@ public record HeuristicAtStop(int minTravelDuration, int minNumTransfers, int mi public String toString() { return this == UNREACHED ? "[]" - : ("[" + + : "[" + (DurationUtils.durationToStr(minTravelDuration) + " ") + (minNumTransfers + "tx ") + OtpNumberFormat.formatCostCenti(minCost) + - "]"); + "]"; } } diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McRangeRaptorWorkerState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McRangeRaptorWorkerState.java index 13de83db0f8..0d401b3311a 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McRangeRaptorWorkerState.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McRangeRaptorWorkerState.java @@ -61,8 +61,8 @@ * * @param The TripSchedule type defined by the user of the raptor API. */ -public final class McRangeRaptorWorkerState - implements RaptorWorkerState { +public final class McRangeRaptorWorkerState implements + RaptorWorkerState { private final McStopArrivals arrivals; private final DestinationArrivalPaths paths; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/MultiCriteriaRoutingStrategy.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/MultiCriteriaRoutingStrategy.java index 75bdd230ffa..80ec5f4023f 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/MultiCriteriaRoutingStrategy.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/MultiCriteriaRoutingStrategy.java @@ -31,8 +31,7 @@ public class MultiCriteriaRoutingStrategy< T extends RaptorTripSchedule, R extends AbstractPatternRide -> - implements RoutingStrategy { +> implements RoutingStrategy { private final McRangeRaptorWorkerState state; private final TimeBasedBoardingSupport boardingSupport; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ViaConnectionStopArrivalEventListener.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ViaConnectionStopArrivalEventListener.java index d3354a9c073..d1365fb36e0 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ViaConnectionStopArrivalEventListener.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ViaConnectionStopArrivalEventListener.java @@ -44,8 +44,8 @@ * performance - we do it here and for the moment does not support pass-through for stops * where alighting is forbidden. */ -public final class ViaConnectionStopArrivalEventListener - implements ParetoSetEventListener> { +public final class ViaConnectionStopArrivalEventListener implements + ParetoSetEventListener> { private static final Logger LOG = LoggerFactory.getLogger( ViaConnectionStopArrivalEventListener.class diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/CalculateTransferToDestination.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/CalculateTransferToDestination.java index c5e84451b64..5b1146f696f 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/CalculateTransferToDestination.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/CalculateTransferToDestination.java @@ -13,8 +13,8 @@ * * @param The TripSchedule type defined by the user of the raptor API. */ -class CalculateTransferToDestination - implements ParetoSetEventListener> { +class CalculateTransferToDestination implements + ParetoSetEventListener> { private final List egressPaths; private final DestinationArrivalPaths destinationArrivals; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/DebugStopArrivalsStatistics.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/DebugStopArrivalsStatistics.java index fdcfc6bab2f..ef59b5c62c4 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/DebugStopArrivalsStatistics.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/DebugStopArrivalsStatistics.java @@ -35,8 +35,8 @@ void debugStatInfo(ParetoSet[] stops) { arrayLen += stop.internalArrayLength(); } } - double avg = ((double) total) / numOfStops; - double arrayLenAvg = ((double) arrayLen) / numOfStops; + double avg = (double) total / numOfStops; + double arrayLenAvg = (double) arrayLen / numOfStops; // Debug stop arrivals statistics. // - For each stop the number of arrivals logged with: diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/AbstractStopArrivalC2.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/AbstractStopArrivalC2.java index 494c2be285e..c928157ea8d 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/AbstractStopArrivalC2.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/AbstractStopArrivalC2.java @@ -9,7 +9,8 @@ */ abstract sealed class AbstractStopArrivalC2 extends McStopArrival - permits AccessStopArrivalC2, TransitStopArrivalC2, TransferStopArrivalC2 { + permits AccessStopArrivalC2, TransitStopArrivalC2, TransferStopArrivalC2 +{ private final int c2; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/ArrivalParetoSetComparatorFactory.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/ArrivalParetoSetComparatorFactory.java index f1663f284d9..ab80f3f1456 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/ArrivalParetoSetComparatorFactory.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/ArrivalParetoSetComparatorFactory.java @@ -36,9 +36,7 @@ public static > ArrivalParetoSetComparatorFactory ); } - public static > ArrivalParetoSetComparatorFactory< - T - > ofCompareC1RelaxedOnC2Dominance( + public static > ArrivalParetoSetComparatorFactory ofCompareC1RelaxedOnC2Dominance( final RelaxFunction relaxC1, final DominanceFunction c2DominanceFunction ) { @@ -82,7 +80,7 @@ private static > ParetoComparator compareFunctionW private static > boolean compareC1(T l, T r) { // This is important with respect to performance. Using the short-circuit logical OR(||) is // faster than bitwise inclusive OR(|) (even between boolean expressions) - return (l.arrivalTime() < r.arrivalTime() || l.round() < r.round() || l.c1() < r.c1()); + return l.arrivalTime() < r.arrivalTime() || l.round() < r.round() || l.c1() < r.c1(); } /** diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/McStopArrival.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/McStopArrival.java index 9aa7d018b08..ca657231237 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/McStopArrival.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/McStopArrival.java @@ -10,7 +10,8 @@ */ public abstract sealed class McStopArrival implements ArrivalView - permits AbstractStopArrivalC2, AccessStopArrival, TransitStopArrival, TransferStopArrival { + permits AbstractStopArrivalC2, AccessStopArrival, TransitStopArrival, TransferStopArrival +{ private final McStopArrival previous; private final int round; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/TransitStopArrival.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/TransitStopArrival.java index 3395d7ea9f0..1b8277c32d4 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/TransitStopArrival.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/TransitStopArrival.java @@ -13,7 +13,8 @@ */ final class TransitStopArrival extends McStopArrival - implements TransitPathView, TransitArrival { + implements TransitPathView, TransitArrival +{ private final T trip; private final int boardStopPosition; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/TransitStopArrivalC2.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/TransitStopArrivalC2.java index e4022046494..88fad597b49 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/TransitStopArrivalC2.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/TransitStopArrivalC2.java @@ -12,7 +12,8 @@ */ final class TransitStopArrivalC2 extends AbstractStopArrivalC2 - implements TransitPathView, TransitArrival { + implements TransitPathView, TransitArrival +{ private final T trip; private final int boardStopPosition; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/AbstractPatternRide.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/AbstractPatternRide.java index f5ca3a4e656..448959719a4 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/AbstractPatternRide.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/AbstractPatternRide.java @@ -63,7 +63,8 @@ */ public abstract sealed class AbstractPatternRide implements PatternRideView> - permits PatternRideC1, PatternRideC2 { + permits PatternRideC1, PatternRideC2 +{ private final McStopArrival prevArrival; private final int boardStopPosition; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/TransitGroupPriorityRideFactory.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/TransitGroupPriorityRideFactory.java index 65a5eb74d2d..3b421d73d73 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/TransitGroupPriorityRideFactory.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/TransitGroupPriorityRideFactory.java @@ -9,8 +9,8 @@ * This factory creates new {@link AbstractPatternRide}s and merge in transit-group-priority ids * into c2. */ -public class TransitGroupPriorityRideFactory - implements PatternRideFactory> { +public class TransitGroupPriorityRideFactory implements + PatternRideFactory> { private int currentPatternGroupPriority; private final RaptorTransitGroupPriorityCalculator transitGroupPriorityCalculator; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/configure/PathConfig.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/configure/PathConfig.java index 24445d6e033..8bae7565528 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/configure/PathConfig.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/configure/PathConfig.java @@ -81,7 +81,9 @@ private ParetoSetTime paretoSetTimeConfig() { ParetoSetTime timeConfig = ctx.searchParams().timetable() ? ParetoSetTime.USE_TIMETABLE - : (preferLatestDeparture ? ParetoSetTime.USE_DEPARTURE_TIME : ParetoSetTime.USE_ARRIVAL_TIME); + : preferLatestDeparture + ? ParetoSetTime.USE_DEPARTURE_TIME + : ParetoSetTime.USE_ARRIVAL_TIME; return timeConfig; } diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/ArrivalTimeRoutingStrategy.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/ArrivalTimeRoutingStrategy.java index ccc39e7a527..8f1d2fba13b 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/ArrivalTimeRoutingStrategy.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/ArrivalTimeRoutingStrategy.java @@ -26,8 +26,8 @@ * * @param The TripSchedule type defined by the user of the raptor API. */ -public final class ArrivalTimeRoutingStrategy - implements RoutingStrategy { +public final class ArrivalTimeRoutingStrategy implements + RoutingStrategy { private static final Logger LOG = LoggerFactory.getLogger(ArrivalTimeRoutingStrategy.class); diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/MinTravelDurationRoutingStrategy.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/MinTravelDurationRoutingStrategy.java index 04b9f8481c8..0cf2b08e146 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/MinTravelDurationRoutingStrategy.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/MinTravelDurationRoutingStrategy.java @@ -28,8 +28,8 @@ * * @param The TripSchedule type defined by the user of the raptor API. */ -public final class MinTravelDurationRoutingStrategy - implements RoutingStrategy { +public final class MinTravelDurationRoutingStrategy implements + RoutingStrategy { private static final Logger LOG = LoggerFactory.getLogger(MinTravelDurationRoutingStrategy.class); diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdRangeRaptorWorkerState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdRangeRaptorWorkerState.java index 43e50735544..4e9605aa8b1 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdRangeRaptorWorkerState.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdRangeRaptorWorkerState.java @@ -29,8 +29,8 @@ * * @param The TripSchedule type defined by the user of the raptor API. */ -public final class StdRangeRaptorWorkerState - implements StdWorkerState { +public final class StdRangeRaptorWorkerState implements + StdWorkerState { /** * The best times to reach each stop, whether via a transfer or via transit directly. This is the diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdTransferEarlyPruning.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdTransferEarlyPruning.java index bae823e5e0e..7187de7bc6d 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdTransferEarlyPruning.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdTransferEarlyPruning.java @@ -75,8 +75,8 @@ public StdTransferEarlyPruning( this.bestDestCurrentIteration = calculator.unreachedTime(); this.currentRound = 0; lifeCycle.onPrepareForNextRound(round -> this.currentRound = round); - lifeCycle.onSetupIteration(ignore -> - this.bestDestCurrentIteration = calculator.unreachedTime() + lifeCycle.onSetupIteration( + ignore -> this.bestDestCurrentIteration = calculator.unreachedTime() ); } diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/BestTimesOnlyStopArrivalsState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/BestTimesOnlyStopArrivalsState.java index 3a9b986c12b..5430cf713e3 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/BestTimesOnlyStopArrivalsState.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/BestTimesOnlyStopArrivalsState.java @@ -21,8 +21,8 @@ * * @param The TripSchedule type defined by the user of the raptor API. */ -public class BestTimesOnlyStopArrivalsState - implements StopArrivalsState { +public class BestTimesOnlyStopArrivalsState implements + StopArrivalsState { private final BestTimes bestTimes; private final SimpleBestNumberOfTransfers bestNumberOfTransfers; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/debug/DebugStopArrivalsState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/debug/DebugStopArrivalsState.java index 69e096bf8fa..5a0d8b5cf19 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/debug/DebugStopArrivalsState.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/debug/DebugStopArrivalsState.java @@ -18,8 +18,8 @@ * * @param The TripSchedule type defined by the user of the raptor API. */ -public final class DebugStopArrivalsState - implements StopArrivalsState { +public final class DebugStopArrivalsState implements + StopArrivalsState { private final StopArrivalsState delegate; private final StateDebugger debug; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/heuristics/HeuristicsAdapter.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/heuristics/HeuristicsAdapter.java index b9d2705b9c8..84eac161d32 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/heuristics/HeuristicsAdapter.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/heuristics/HeuristicsAdapter.java @@ -138,12 +138,10 @@ private int bestNumOfTransfers(int stop) { } private int bestGeneralizedCost(int stop) { - return ( - costCalculator.calculateRemainingMinCost( - bestTravelDuration(stop), - bestNumOfTransfers(stop), - stop - ) + return costCalculator.calculateRemainingMinCost( + bestTravelDuration(stop), + bestNumOfTransfers(stop), + stop ); } diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/AccessStopArrivalState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/AccessStopArrivalState.java index 740d0b5bc79..ee71e76559f 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/AccessStopArrivalState.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/AccessStopArrivalState.java @@ -14,8 +14,8 @@ * well as the default state. There are relatively few access states, so the memory and performance * overhead is small. */ -public final class AccessStopArrivalState - implements StopArrivalState { +public final class AccessStopArrivalState implements + StopArrivalState { private final DefaultStopArrivalState delegate; private RaptorAccessEgress accessArriveOnStreet; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/DefaultStopArrivalState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/DefaultStopArrivalState.java index df3810a3672..ab0f7ac18f4 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/DefaultStopArrivalState.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/DefaultStopArrivalState.java @@ -25,7 +25,8 @@ */ sealed class DefaultStopArrivalState implements StopArrivalState - permits EgressStopArrivalState { + permits EgressStopArrivalState +{ /** * Used to initialize all none-time-based attributes. @@ -186,7 +187,7 @@ private String tripInfo() { return boardStopPosition == NOT_SET ? null : trip.pattern().debugInfo() + - " @" + - TimeUtils.timeToStrCompact(trip.departure(boardStopPosition)); + " @" + + TimeUtils.timeToStrCompact(trip.departure(boardStopPosition)); } } diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/EgressStopArrivalState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/EgressStopArrivalState.java index a71f6248267..03c85a41ede 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/EgressStopArrivalState.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/EgressStopArrivalState.java @@ -14,8 +14,7 @@ * * @param The TripSchedule type defined by the user of the raptor API. */ -final class EgressStopArrivalState - extends DefaultStopArrivalState { +final class EgressStopArrivalState extends DefaultStopArrivalState { private final int round; private final int stop; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivals.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivals.java index c7c3ae4072d..4e4f27e778a 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivals.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivals.java @@ -36,17 +36,15 @@ public void setupEgressStopStates( ) { for (int i = 1; i < arrivals.length; i++) { final int round = i; - egressPaths - .byStop() - .forEachEntry((stop, list) -> { - arrivals[round][stop] = new EgressStopArrivalState<>( - stop, - round, - list, - destinationArrivalListener - ); - return true; - }); + egressPaths.byStop().forEachEntry((stop, list) -> { + arrivals[round][stop] = new EgressStopArrivalState<>( + stop, + round, + list, + destinationArrivalListener + ); + return true; + }); } } diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivalsState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivalsState.java index 9128a3b5ef6..ecc4a97cf90 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivalsState.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivalsState.java @@ -17,8 +17,8 @@ * * @param The TripSchedule type defined by the user of the raptor API. */ -public final class StdStopArrivalsState - implements StopArrivalsState { +public final class StdStopArrivalsState implements + StopArrivalsState { private final StdStopArrivals stops; private final DestinationArrivalPaths results; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/path/EgressArrivalToPathAdapter.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/path/EgressArrivalToPathAdapter.java index 743c745a119..6d883bf05b1 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/path/EgressArrivalToPathAdapter.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/path/EgressArrivalToPathAdapter.java @@ -29,8 +29,9 @@ * * @param The TripSchedule type defined by the user of the raptor API. */ -public class EgressArrivalToPathAdapter - implements ArrivedAtDestinationCheck, DestinationArrivalListener { +public class EgressArrivalToPathAdapter implements + ArrivedAtDestinationCheck, + DestinationArrivalListener { private final DestinationArrivalPaths paths; private final TransitCalculator calculator; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Access.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Access.java index 66a7bb935eb..1b1d05e22d4 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Access.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Access.java @@ -12,7 +12,8 @@ final class Access extends StopArrivalViewAdapter - implements AccessPathView { + implements AccessPathView +{ private final int arrivalTime; private final RaptorAccessEgress access; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Transit.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Transit.java index ec2606353fb..717a4d1c2ca 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Transit.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Transit.java @@ -12,7 +12,8 @@ final class Transit extends StopArrivalViewAdapter - implements TransitPathView { + implements TransitPathView +{ private final StopArrivalState arrival; private final StopsCursor cursor; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/support/RouterResultPathAggregator.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/support/RouterResultPathAggregator.java index e61efb1ccd1..f7e5578efcb 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/support/RouterResultPathAggregator.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/support/RouterResultPathAggregator.java @@ -20,8 +20,8 @@ * them across all segments could introduce unnecessary overhead and risk if these methods were * ever called as part of a normal transit search. */ -public class RouterResultPathAggregator - implements RaptorRouterResult { +public class RouterResultPathAggregator implements + RaptorRouterResult { // Keep the result of one of the segments, and provide it for the one-to-many // statistics results methods. See JavaDoc on class. diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java index 9a22407e5c2..960faa6087d 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java @@ -55,11 +55,11 @@ public final class AccessEgressFunctions { * */ private static final ParetoComparator STANDARD_COMPARATOR = (l, r) -> - ((l.arrivedOnBoard() && !r.arrivedOnBoard()) || - r.hasOpeningHours() || - l.numberOfRides() < r.numberOfRides() || - l.durationInSeconds() < r.durationInSeconds() || - l.numberOfViaLocationsVisited() > r.numberOfViaLocationsVisited()); + (l.arrivedOnBoard() && !r.arrivedOnBoard()) || + r.hasOpeningHours() || + l.numberOfRides() < r.numberOfRides() || + l.durationInSeconds() < r.durationInSeconds() || + l.numberOfViaLocationsVisited() > r.numberOfViaLocationsVisited(); /** * Filter Multi-criteria Raptor access and egress paths. This can be used to wash diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardRaptorTransitCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardRaptorTransitCalculator.java index 49789f9e89b..b826bd83321 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardRaptorTransitCalculator.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardRaptorTransitCalculator.java @@ -17,7 +17,8 @@ public final class ForwardRaptorTransitCalculator extends ForwardTransitCalculator - implements RaptorTransitCalculator { + implements RaptorTransitCalculator +{ private final int earliestDepartureTime; private final int searchWindowInSeconds; @@ -41,9 +42,10 @@ public ForwardRaptorTransitCalculator( ) { this.earliestDepartureTime = earliestDepartureTime; this.searchWindowInSeconds = searchWindowInSeconds; - this.latestAcceptableArrivalTime = latestAcceptableArrivalTime == RaptorConstants.TIME_NOT_SET - ? unreachedTime() - : latestAcceptableArrivalTime; + this.latestAcceptableArrivalTime = + latestAcceptableArrivalTime == RaptorConstants.TIME_NOT_SET + ? unreachedTime() + : latestAcceptableArrivalTime; this.iterationStep = iterationStep; } diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTransitCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTransitCalculator.java index 5a53312a83f..93a40f6abf8 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTransitCalculator.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTransitCalculator.java @@ -9,7 +9,8 @@ */ public class ForwardTransitCalculator extends ForwardTimeCalculator - implements TransitCalculator { + implements TransitCalculator +{ public ForwardTransitCalculator() {} diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorTransitCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorTransitCalculator.java index 045c7bb6fe4..0b2858dd31d 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorTransitCalculator.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorTransitCalculator.java @@ -42,8 +42,8 @@ * * @param The TripSchedule type defined by the user of the raptor API. */ -public interface RaptorTransitCalculator - extends TransitCalculator { +public interface RaptorTransitCalculator extends + TransitCalculator { /** * Return a calculator for test purpose. The following parameters are fixed: *

    diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseRaptorTransitCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseRaptorTransitCalculator.java index 518b02ba3ee..41cfbb9862a 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseRaptorTransitCalculator.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseRaptorTransitCalculator.java @@ -17,7 +17,8 @@ public final class ReverseRaptorTransitCalculator extends ReverseTransitCalculator - implements RaptorTransitCalculator { + implements RaptorTransitCalculator +{ private final int latestArrivalTime; private final int searchWindowInSeconds; @@ -43,10 +44,10 @@ public ReverseRaptorTransitCalculator(SearchParams s, RaptorTuningParameters t) ) { this.latestArrivalTime = latestArrivalTime; this.searchWindowInSeconds = searchWindowInSeconds; - this.earliestAcceptableDepartureTime = earliestAcceptableDepartureTime == - RaptorConstants.TIME_NOT_SET - ? unreachedTime() - : earliestAcceptableDepartureTime; + this.earliestAcceptableDepartureTime = + earliestAcceptableDepartureTime == RaptorConstants.TIME_NOT_SET + ? unreachedTime() + : earliestAcceptableDepartureTime; this.iterationStep = iterationStep; } diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTransitCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTransitCalculator.java index bd5648cc523..2d2afc4c46e 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTransitCalculator.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTransitCalculator.java @@ -10,7 +10,8 @@ */ public class ReverseTransitCalculator extends ReverseTimeCalculator - implements TransitCalculator { + implements TransitCalculator +{ @Override public int stopArrivalTime(T onTrip, int stopPositionInPattern, int alightSlack) { diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TripScheduleExactMatchSearch.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TripScheduleExactMatchSearch.java index 293482d2073..2a6019ea117 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TripScheduleExactMatchSearch.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TripScheduleExactMatchSearch.java @@ -18,8 +18,8 @@ * * @param The TripSchedule type defined by the user of the raptor API. */ -public final class TripScheduleExactMatchSearch - implements RaptorTripScheduleSearch { +public final class TripScheduleExactMatchSearch implements + RaptorTripScheduleSearch { private final int slack; private final RaptorTripScheduleSearch delegate; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/spi/EmptyBoardOrAlightEvent.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/EmptyBoardOrAlightEvent.java index 3a9c219e105..2f8b4c80e9e 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/spi/EmptyBoardOrAlightEvent.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/spi/EmptyBoardOrAlightEvent.java @@ -2,8 +2,9 @@ import org.opentripplanner.utils.time.TimeUtils; -record EmptyBoardOrAlightEvent(int earliestBoardTime) implements - RaptorBoardOrAlightEvent { +record EmptyBoardOrAlightEvent( + int earliestBoardTime +) implements RaptorBoardOrAlightEvent { @Override public int tripScheduleIndex() { return RaptorConstants.NOT_FOUND; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/spi/IntIterators.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/IntIterators.java index 631dda65d03..cf5cc72856c 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/spi/IntIterators.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/spi/IntIterators.java @@ -72,7 +72,7 @@ public static IntIterator intIncIterator( @Override public int next() { - return i += increment; + return (i += increment); } @Override diff --git a/raptor/src/test-fixtures/java/org/opentripplanner/raptor/api/model/RaptorAccessEgressToStringParser.java b/raptor/src/test-fixtures/java/org/opentripplanner/raptor/api/model/RaptorAccessEgressToStringParser.java index 51e71448d68..524082cec9b 100644 --- a/raptor/src/test-fixtures/java/org/opentripplanner/raptor/api/model/RaptorAccessEgressToStringParser.java +++ b/raptor/src/test-fixtures/java/org/opentripplanner/raptor/api/model/RaptorAccessEgressToStringParser.java @@ -90,7 +90,7 @@ private RaptorAccessEgressToStringParser parse() { throw new IllegalArgumentException("'" + input + "' does not match :/" + PARSE_INPUT + "'"); } var stopValue = m.group(4); - this.stopIndex = (stopValue.matches("\\d+")) + this.stopIndex = stopValue.matches("\\d+") ? Integer.parseInt(stopValue) : stopIndexResolver.applyAsInt(stopValue); diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/AccessAndEgressWithOpeningHoursPathTestCase.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/AccessAndEgressWithOpeningHoursPathTestCase.java index a600cd79989..07ad2d072c0 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/AccessAndEgressWithOpeningHoursPathTestCase.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/AccessAndEgressWithOpeningHoursPathTestCase.java @@ -375,7 +375,7 @@ private static int costL1ForwardIncWait(int prevArrivalTime) { } private static int costL1ReverseIncWait(int prevArrivalTime) { - int waitTime = (prevArrivalTime - L1_END) + BOARD_SLACK; + int waitTime = prevArrivalTime - L1_END + BOARD_SLACK; return toRaptorCost(waitTime * WAIT_RELUCTANCE) + L1_C1_EX_WAIT; } } diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedBoardingSearch.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedBoardingSearch.java index 91ea03851a7..939f216d569 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedBoardingSearch.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedBoardingSearch.java @@ -15,7 +15,8 @@ import org.opentripplanner.utils.tostring.ToStringBuilder; public class TestConstrainedBoardingSearch - implements RaptorConstrainedBoardingSearch { + implements RaptorConstrainedBoardingSearch +{ /** Index of guaranteed transfers by fromStopPos */ private final TIntObjectMap> transfersByFromStopPos = diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedTransfer.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedTransfer.java index ed9072161de..b28ac06802c 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedTransfer.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedTransfer.java @@ -9,7 +9,8 @@ import org.opentripplanner.utils.tostring.ToStringBuilder; class TestConstrainedTransfer - implements RaptorConstrainedTransfer, RaptorBoardOrAlightEvent { + implements RaptorConstrainedTransfer, RaptorBoardOrAlightEvent +{ private final TestTransferConstraint transferConstraint; private final TestTripSchedule sourceTrip; diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestCostCalculator.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestCostCalculator.java index 93a8485503b..8f90fd8e78d 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestCostCalculator.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestCostCalculator.java @@ -105,14 +105,14 @@ public int calculateRemainingMinCost( if (minNumTransfers > -1) { return ( boardCost + - ((boardCost + transferCost) * minNumTransfers) + - (TRANSIT_RELUCTANCE * minTravelDuration) + (boardCost + transferCost) * minNumTransfers + + TRANSIT_RELUCTANCE * minTravelDuration ); } else { // Remove cost that was added during alighting similar as we do in the costEgress() method return stopBoardAlightTransferCosts == null - ? (TRANSIT_RELUCTANCE * minTravelDuration) - : (TRANSIT_RELUCTANCE * minTravelDuration) - stopBoardAlightTransferCosts[fromStopIndex]; + ? TRANSIT_RELUCTANCE * minTravelDuration + : TRANSIT_RELUCTANCE * minTravelDuration - stopBoardAlightTransferCosts[fromStopIndex]; } } @@ -146,7 +146,7 @@ public int boardingCostRegularTransfer( int cost = waitFactor * boardWaitTime; - cost += firstBoarding ? boardCost : (boardCost + transferCost); + cost += firstBoarding ? boardCost : boardCost + transferCost; // If it's first boarding event then it is not a transfer if (stopBoardAlightTransferCosts != null && !firstBoarding) { diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransitData.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransitData.java index 068952d9a9e..6b5f1059a84 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransitData.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransitData.java @@ -30,7 +30,8 @@ @SuppressWarnings("UnusedReturnValue") public class TestTransitData - implements RaptorTransitDataProvider, RaptorTestConstants { + implements RaptorTransitDataProvider, RaptorTestConstants +{ private static final AtomicInteger WARNING_COUNTER = new AtomicInteger(0); @@ -65,7 +66,11 @@ public TestTransitData() { } public TestTransitData access(String... accessList) { - access(Arrays.stream(accessList).map(TestAccessEgress::of).toArray(TestAccessEgress[]::new)); + access( + Arrays.stream(accessList) + .map(TestAccessEgress::of) + .toArray(TestAccessEgress[]::new) + ); return this; } @@ -175,7 +180,8 @@ public RaptorStopNameResolver stopNameResolver() { @Override public int getValidTransitDataStartTime() { - return this.routes.stream() + return this.routes + .stream() .mapToInt(route -> route.timetable().getTripSchedule(0).departure(0)) .min() .orElseThrow(); @@ -183,7 +189,8 @@ public int getValidTransitDataStartTime() { @Override public int getValidTransitDataEndTime() { - return this.routes.stream() + return this.routes + .stream() .mapToInt(route -> { RaptorTimeTable timetable = route.timetable(); RaptorTripPattern pattern = route.pattern(); @@ -251,7 +258,7 @@ public TestTransitData withTimetables(String routeTimetables) { if (ROUTE_NAME_PATTERN.matcher(firstLine.trim()).matches()) { withTimetable(firstLine, timetable.substring(firstLine.length() + 1).trim()); } else { - withTimetable("R" + (++routeIndex), timetable.trim()); + withTimetable("R" + ++routeIndex, timetable.trim()); } } } diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripScheduleSearch.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripScheduleSearch.java index dfad37fd94f..c5805ec7478 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripScheduleSearch.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripScheduleSearch.java @@ -11,8 +11,8 @@ import org.opentripplanner.utils.tostring.ToStringBuilder; class TestTripScheduleSearch - implements - RaptorTripScheduleSearch, RaptorBoardOrAlightEvent { + implements RaptorTripScheduleSearch, RaptorBoardOrAlightEvent +{ private final List trips; private final SearchDirection direction; diff --git a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/C01_TransferBoardAndAlightSlackTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/C01_TransferBoardAndAlightSlackTest.java index 0ac934878d6..056b90b6845 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/C01_TransferBoardAndAlightSlackTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/C01_TransferBoardAndAlightSlackTest.java @@ -57,9 +57,13 @@ void setup() { // earliest-departure-time: 0:03:00 + 10s + 1m + 30s = 0:04:40 route(pattern("R2", STOP_C, STOP_D)).withTimetable( // Missed by 1 second - schedule().departures("00:04:40 00:05:10").arrDepOffset(D10_s), + schedule() + .departures("00:04:40 00:05:10") + .arrDepOffset(D10_s), // Exact match - schedule().departures("00:04:41 00:05:11").arrDepOffset(D10_s) + schedule() + .departures("00:04:41 00:05:11") + .arrDepOffset(D10_s) ) ) // Ends 30s after last stop arrival: 10s alight-slack + 20s walk diff --git a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/C02_OnStreetTransfersTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/C02_OnStreetTransfersTest.java index c13b1bb736b..a51bab857f2 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/C02_OnStreetTransfersTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/C02_OnStreetTransfersTest.java @@ -54,9 +54,13 @@ public void setup() { .withRoute( route(pattern("R2", STOP_D, STOP_E)).withTimetable( // Missed by 1 second - schedule().departures("00:03:59, 00:05:09").arrDepOffset(D10_s), + schedule() + .departures("00:03:59, 00:05:09") + .arrDepOffset(D10_s), // Exact match - schedule().departures("00:04:00, 00:05:10").arrDepOffset(D10_s) + schedule() + .departures("00:04:00, 00:05:10") + .arrDepOffset(D10_s) ) ) // Ends 30s after last stop arrival: 10s alight-slack + 20s walk diff --git a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F03_AccessEgressWithRidesBoardAndAlightSlackTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F03_AccessEgressWithRidesBoardAndAlightSlackTest.java index 6a2a9e8d144..f4c5b3a7ac2 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F03_AccessEgressWithRidesBoardAndAlightSlackTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F03_AccessEgressWithRidesBoardAndAlightSlackTest.java @@ -47,7 +47,9 @@ public void setup() { // --> 00:00:00 + flex 30s + slack(1m + 30s) = 00:02:00 schedule().departures("0:03:29 0:05:29"), // This is the trip we expect to board - schedule().departures("0:04:00 0:10:00").arrivals("0 00:06:00"), + schedule() + .departures("0:04:00 0:10:00") + .arrivals("0 00:06:00"), // REVERSE SEARCH: The last trip arrives too late: It takes 1m40s to get to the // point of "boarding" in the reverse search: // --> 00:10:00 - (flex 20s + slack(1m + 10s)) = 00:08:30 (arrival time) diff --git a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F12_EgressWithRidesMultipleOptimalPathsTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F12_EgressWithRidesMultipleOptimalPathsTest.java index 78e0f90fa06..630e2985be0 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F12_EgressWithRidesMultipleOptimalPathsTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F12_EgressWithRidesMultipleOptimalPathsTest.java @@ -69,17 +69,15 @@ public class F12_EgressWithRidesMultipleOptimalPathsTest implements RaptorTestCo @BeforeEach public void setup() { - data - .access("Free ~ A") - .withTimetables( - """ - A C - 0:04 0:20 - -- - A B - 0:05 0:16 - """ - ); + data.access("Free ~ A").withTimetables( + """ + A C + 0:04 0:20 + -- + A B + 0:05 0:16 + """ + ); // We will test board- and alight-slack in a separate test data.withSlackProvider(new TestSlackProvider(D1_m, D0_s, D0_s)); diff --git a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/G01_AccessWithOpeningHoursTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/G01_AccessWithOpeningHoursTest.java index 300aeaf6416..9d90a774b07 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/G01_AccessWithOpeningHoursTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/G01_AccessWithOpeningHoursTest.java @@ -62,14 +62,14 @@ public void setup() { data .withTimetables( """ - B E - 00:15 00:30 - 00:20 00:35 - 00:25 00:40 - 00:30 00:45 - 24:15 24:30 - 24:20 24:35 - """ + + B E + 00:15 00:30 + 00:20 00:35 + 00:25 00:40 + 00:30 00:45 + 24:15 24:30 + 24:20 24:35 + """ + // Not within time-limit 24:42 (need 2 min for egress) "24:25 24:40" ) diff --git a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/G02_EgressWithOpeningHoursTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/G02_EgressWithOpeningHoursTest.java index f052b85d8e0..4def243129a 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/G02_EgressWithOpeningHoursTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/G02_EgressWithOpeningHoursTest.java @@ -46,17 +46,15 @@ public class G02_EgressWithOpeningHoursTest implements RaptorTestConstants { @BeforeEach public void setup() { - data - .access("Free ~ A") - .withTimetables( - """ - A B - 00:10 00:20 - 00:20 00:30 - 00:30 00:40 - 24:20 24:30 - """ - ); + data.access("Free ~ A").withTimetables( + """ + A B + 00:10 00:20 + 00:20 00:30 + 00:30 00:40 + 24:20 24:30 + """ + ); requestBuilder .searchParams() diff --git a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/I02_C2DestinationPruningTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/I02_C2DestinationPruningTest.java index 30994a204b4..5736fd40870 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/I02_C2DestinationPruningTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/I02_C2DestinationPruningTest.java @@ -68,7 +68,7 @@ void c2DestinationPruningWithTransitPriority() { requestBuilder.withMultiCriteria(mc -> mc - .withRelaxC1(value -> ((value * 110) / 100)) + .withRelaxC1(value -> (value * 110) / 100) .withTransitPriorityCalculator(new TestGroupPriorityCalculator()) ); diff --git a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/J02_ViaStopSearchTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/J02_ViaStopSearchTest.java index ddd6b6c699a..34d43facdb1 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/J02_ViaStopSearchTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/J02_ViaStopSearchTest.java @@ -160,9 +160,9 @@ void viaSearchArrivingByTransferAtViaStop() { void accessWalkToViaStopWithoutTransit() { data.withTimetables( """ - A B C D - 0:02 0:05 0:10 0:15 - """ + + A B C D + 0:02 0:05 0:10 0:15 + """ + // We add another trip to allow riding trip one - via B - then ride trip two, this // is not a pareto-optimal solution and should only appear if there is something wrong. """ diff --git a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java index b31d44b6edd..d57bca60779 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java @@ -83,8 +83,8 @@ void prepareRequest() { .timetable(true); requestBuilder.withMultiCriteria(mc -> - // Raptor cost 9000 ~= 90 seconds slack mc + // Raptor cost 9000 ~= 90 seconds slack .withRelaxC1(value -> value + C1_SLACK_90_s) .withTransitPriorityCalculator(PRIORITY_GROUP_CALCULATOR) ); diff --git a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java index fc1725be634..23f76ee25a5 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java @@ -85,8 +85,8 @@ void prepareRequest() { .timetable(true); requestBuilder.withMultiCriteria(mc -> - // Raptor cost 9000 ~= 90 seconds slack mc + // Raptor cost 9000 ~= 90 seconds slack .withRelaxC1(value -> value + C1_SLACK_90_s) .withTransitPriorityCalculator(PRIORITY_GROUP_CALCULATOR) ); diff --git a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/ExpectedList.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/ExpectedList.java index f82775b3c7b..991156fe522 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/ExpectedList.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/ExpectedList.java @@ -38,6 +38,8 @@ public String[] get(int... indexes) { } public String[] range(int startInclusive, int endExclusive) { - return Arrays.stream(items, startInclusive, endExclusive).toList().toArray(new String[0]); + return Arrays.stream(items, startInclusive, endExclusive) + .toList() + .toArray(new String[0]); } } diff --git a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestCase.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestCase.java index ce1e191652d..cfda2861462 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestCase.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestCase.java @@ -64,9 +64,8 @@ public String runDetailedResult( @Override public String toString() { String profile = config.profile().name().toLowerCase(); - String optimizations = config == RaptorModuleTestConfig.TC_MULTI_CRITERIA_DEST_PRUNING - ? " w/dest-pruning" - : ""; + String optimizations = + config == RaptorModuleTestConfig.TC_MULTI_CRITERIA_DEST_PRUNING ? " w/dest-pruning" : ""; String oneIteration = config.withOneIteration() ? " one-iteration" : ""; String reverse = config.isReverse() ? " reverse" : ""; return profile + optimizations + reverse + oneIteration; diff --git a/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/StopArrivalStateParetoSetTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/StopArrivalStateParetoSetTest.java index b07c47e0b43..4cc3fea4bb1 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/StopArrivalStateParetoSetTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/StopArrivalStateParetoSetTest.java @@ -17,7 +17,7 @@ public class StopArrivalStateParetoSetTest { // 08:35 in seconds - private static final int A_TIME = ((8 * 60) + 35) * 60; + private static final int A_TIME = (8 * 60 + 35) * 60; private static final int ANY = 3; private static final int ROUND_1 = 1; private static final int ROUND_2 = 2; diff --git a/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/TestStopArivalFactory.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/TestStopArivalFactory.java index 4daa0353f6a..20e5b3ee08e 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/TestStopArivalFactory.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/stop/TestStopArivalFactory.java @@ -49,7 +49,11 @@ private TestStopArivalFactory( nLegs = 1 + nRounds + (arriveOnBoard ? 0 : 1); this.trasitLegCoeficient = 1.0f / nRounds; } - this.stops = new ArrayDeque<>(IntStream.range(1, nLegs + 1).boxed().toList()); + this.stops = new ArrayDeque<>( + IntStream.range(1, nLegs + 1) + .boxed() + .toList() + ); this.legCoeficient = 1.0f / nLegs; } diff --git a/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorSearchWindowCalculatorTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorSearchWindowCalculatorTest.java index 49714c7d2f6..21f0cedb921 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorSearchWindowCalculatorTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorSearchWindowCalculatorTest.java @@ -78,7 +78,7 @@ public void calcEarliestDeparture() { assertTrue( minTransitTime > subject.getLatestArrivalTime() - - (subject.getSearchWindowSeconds() + subject.getEarliestDepartureTime()) + (subject.getSearchWindowSeconds() + subject.getEarliestDepartureTime()) ); } diff --git a/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerTest.java b/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerTest.java index fc24d04a643..eb73c1d1ba7 100644 --- a/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerTest.java @@ -9,9 +9,8 @@ public class ParetoSetEventListenerTest { // Given a set and function - private final TestParetoSetEventListener listener = new TestParetoSetEventListener< - TestVector - >(); + private final TestParetoSetEventListener listener = + new TestParetoSetEventListener(); @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") private final ParetoSet subject = ParetoSet.of( diff --git a/renovate.json5 b/renovate.json5 index f0583f321ed..1c2f91b0c0a 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -92,7 +92,7 @@ "org.apache.maven.plugins:maven-gpg-plugin", "org.codehaus.mojo:build-helper-maven-plugin", "org.apache.maven.plugins:maven-source-plugin", - "com.hubspot.maven.plugins:prettier-maven-plugin", + "com.diffplug.spotless:spotless-maven-plugin", "com.google.cloud.tools:jib-maven-plugin", "com.puppycrawl.tools:checkstyle", "org.apache.maven.plugins:maven-shade-plugin", diff --git a/street/pom.xml b/street/pom.xml index aafee6c8cbf..be82677966f 100644 --- a/street/pom.xml +++ b/street/pom.xml @@ -15,8 +15,8 @@ - com.hubspot.maven.plugins - prettier-maven-plugin + com.diffplug.spotless + spotless-maven-plugin diff --git a/street/src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleType.java b/street/src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleType.java index 050b7b5badf..5bad8aed132 100644 --- a/street/src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleType.java +++ b/street/src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleType.java @@ -73,16 +73,14 @@ public Builder copyOf() { } public static RentalVehicleType getDefaultType(String systemId) { - return DEFAULT_VEHICLE_FOR_SYSTEM.computeIfAbsent( - systemId, - (id -> - new RentalVehicleType( - new FeedScopedId(id, "DEFAULT"), - I18NString.of("Default vehicle type"), - RentalFormFactor.BICYCLE, - PropulsionType.HUMAN, - null - )) + return DEFAULT_VEHICLE_FOR_SYSTEM.computeIfAbsent(systemId, id -> + new RentalVehicleType( + new FeedScopedId(id, "DEFAULT"), + I18NString.of("Default vehicle type"), + RentalFormFactor.BICYCLE, + PropulsionType.HUMAN, + null + ) ); } diff --git a/street/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalStation.java b/street/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalStation.java index 78c61ee3b3c..060ff12bff4 100644 --- a/street/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalStation.java +++ b/street/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalStation.java @@ -350,7 +350,7 @@ public boolean equals(Object o) { isReturning == that.isReturning && overloadingAllowed == that.overloadingAllowed && isArrivingInRentalVehicleAtDestinationAllowed == - that.isArrivingInRentalVehicleAtDestinationAllowed && + that.isArrivingInRentalVehicleAtDestinationAllowed && realTimeData == that.realTimeData && Objects.equals(id, that.id) && Objects.equals(name, that.name) && diff --git a/street/src/main/java/org/opentripplanner/service/vehiclerental/street/geofencing/GeofencingBoundaryEnforcement.java b/street/src/main/java/org/opentripplanner/service/vehiclerental/street/geofencing/GeofencingBoundaryEnforcement.java index 1c46d09242a..27d6804521a 100644 --- a/street/src/main/java/org/opentripplanner/service/vehiclerental/street/geofencing/GeofencingBoundaryEnforcement.java +++ b/street/src/main/java/org/opentripplanner/service/vehiclerental/street/geofencing/GeofencingBoundaryEnforcement.java @@ -30,7 +30,8 @@ *
*/ sealed interface GeofencingBoundaryEnforcement - permits BusinessAreaEnforcement, RestrictedZoneEnforcement { + permits BusinessAreaEnforcement, RestrictedZoneEnforcement +{ /** Forward search: current edge ends at the outside vertex; next edge will enter the zone. */ @Nullable default State[] forwardApproachingEntry(GeofencingZone zone, State state, EdgeTraversal edge) { diff --git a/street/src/main/java/org/opentripplanner/street/geometry/CompactLineStringSequence.java b/street/src/main/java/org/opentripplanner/street/geometry/CompactLineStringSequence.java index e8e7114d079..1013e2c8af8 100644 --- a/street/src/main/java/org/opentripplanner/street/geometry/CompactLineStringSequence.java +++ b/street/src/main/java/org/opentripplanner/street/geometry/CompactLineStringSequence.java @@ -109,7 +109,7 @@ public LineString concatenate(int fromIndex, int toIndexExclusive) { totalCoords += geometries[i].coordinateCount(); } // Each seam between two consecutive members repeats one coordinate; emit it only once. - totalCoords -= (count - 1); + totalCoords -= count - 1; if (totalCoords <= 0) { return GeometryUtils.emptyLineString(); } diff --git a/street/src/main/java/org/opentripplanner/street/geometry/DirectionUtils.java b/street/src/main/java/org/opentripplanner/street/geometry/DirectionUtils.java index e0d0c985947..7b780497865 100644 --- a/street/src/main/java/org/opentripplanner/street/geometry/DirectionUtils.java +++ b/street/src/main/java/org/opentripplanner/street/geometry/DirectionUtils.java @@ -16,7 +16,7 @@ private DirectionUtils() {} public static double getAzimuth(Coordinate a, Coordinate b) { double cosLat = Math.cos(Math.toRadians((a.y + b.y) / 2.0)); // in degrees, we do not care about the units - double dY = (b.y - a.y); + double dY = b.y - a.y; // same double dX = (b.x - a.x) * cosLat; if (Math.abs(dX) < 1e-10 && Math.abs(dY) < 1e-10) { diff --git a/street/src/main/java/org/opentripplanner/street/geometry/EndpointContextLineString.java b/street/src/main/java/org/opentripplanner/street/geometry/EndpointContextLineString.java index f4bb3df3a5d..bd52830d336 100644 --- a/street/src/main/java/org/opentripplanner/street/geometry/EndpointContextLineString.java +++ b/street/src/main/java/org/opentripplanner/street/geometry/EndpointContextLineString.java @@ -109,9 +109,8 @@ public static LineString uncompact( double y0 = reverse ? yb : ya; double x1 = reverse ? xa : xb; double y1 = reverse ? ya : yb; - int intermediateCount = packedCoords == null - ? 0 - : DlugoszVarLenIntPacker.countValues(packedCoords) / 2; + int intermediateCount = + packedCoords == null ? 0 : DlugoszVarLenIntPacker.countValues(packedCoords) / 2; double[] c = new double[(intermediateCount + 2) * 2]; c[0] = x0; c[1] = y0; diff --git a/street/src/main/java/org/opentripplanner/street/geometry/PolylineEncoder.java b/street/src/main/java/org/opentripplanner/street/geometry/PolylineEncoder.java index 32460e38bdb..f6c0fff838f 100644 --- a/street/src/main/java/org/opentripplanner/street/geometry/PolylineEncoder.java +++ b/street/src/main/java/org/opentripplanner/street/geometry/PolylineEncoder.java @@ -132,9 +132,9 @@ public static PolylineEncoderResult encodeCoordinateSequence(CoordinateSequence private static String encodeSignedNumber(int num) { int sgn_num = num << 1; if (num < 0) { - sgn_num = ~(sgn_num); + sgn_num = ~sgn_num; } - return (encodeNumber(sgn_num)); + return encodeNumber(sgn_num); } /** @@ -163,12 +163,12 @@ private static String encodeNumber(int num) { while (num >= 0x20) { int nextValue = (0x20 | (num & 0x1f)) + 63; - encodeString.append((char) (nextValue)); + encodeString.append((char) nextValue); num >>= 5; } num += 63; - encodeString.append((char) (num)); + encodeString.append((char) num); return encodeString.toString(); } diff --git a/street/src/main/java/org/opentripplanner/street/geometry/SphericalDistanceLibrary.java b/street/src/main/java/org/opentripplanner/street/geometry/SphericalDistanceLibrary.java index ab98dc7d032..bfc11fcedb6 100644 --- a/street/src/main/java/org/opentripplanner/street/geometry/SphericalDistanceLibrary.java +++ b/street/src/main/java/org/opentripplanner/street/geometry/SphericalDistanceLibrary.java @@ -220,7 +220,7 @@ public static double metersToDegrees(double distanceMeters) { * converge toward the poles. */ public static double degreesLatitudeToMeters(double degreesLatitude) { - return ((2 * Math.PI * RADIUS_OF_EARTH_IN_M) * degreesLatitude) / 360; + return (2 * Math.PI * RADIUS_OF_EARTH_IN_M * degreesLatitude) / 360; } /** diff --git a/street/src/main/java/org/opentripplanner/street/graph/Graph.java b/street/src/main/java/org/opentripplanner/street/graph/Graph.java index 6f6e44143c0..561db32252f 100644 --- a/street/src/main/java/org/opentripplanner/street/graph/Graph.java +++ b/street/src/main/java/org/opentripplanner/street/graph/Graph.java @@ -4,13 +4,13 @@ import jakarta.inject.Inject; import java.io.Serializable; import java.util.Collection; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import javax.annotation.Nullable; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; @@ -19,7 +19,6 @@ import org.opentripplanner.street.Scope; import org.opentripplanner.street.geometry.CompactElevationProfile; import org.opentripplanner.street.geometry.GeometryUtils; -import org.opentripplanner.street.internal.notes.StreetNotesService; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.openinghours.OpeningHoursCalendarService; @@ -59,9 +58,6 @@ public class Graph implements Serializable { private static final Logger LOG = LoggerFactory.getLogger(Graph.class); - /** Attaches text notes to street edges, which do not affect routing. */ - public final StreetNotesService streetNotesService = new StreetNotesService(); - // Ideally we could just get rid of vertex labels, but they're used in tests and graph building. private final Map vertices = new ConcurrentHashMap<>(); @@ -143,7 +139,6 @@ public void removeEdge(Edge e) { } public void removeEdge(Edge e, Scope scope) { - streetNotesService.removeStaticNotes(e); e.remove(); if (streetIndex != null) { streetIndex.remove(e, scope); @@ -204,33 +199,42 @@ public Optional findStationCentroidVertex(FeedScopedId st } /** - * Return all the edges in the graph. Derived from vertices on demand. + * Lazily iterate over all the edges in the graph, derived from vertices on demand, without + * materializing an intermediate collection. Can be reused/iterated over multiple times. + *

+ * Use {@link ListUtils#ofIterable} to materialize a {@link List} if a {@link Collection} is + * required (e.g. serialization). + *

+ * THREAD SAFTY - This method does not support concurent use. The behavior is undefined. */ - public Collection getEdges() { - Set edges = new HashSet<>(); - for (Vertex v : this.getVertices()) { - edges.addAll(v.getOutgoing()); - } - return edges; - } - - public List getEdgesOfType(Class cls) { - return this.getEdges() - .stream() - .filter(cls::isInstance) - .map(cls::cast) - .collect(Collectors.toList()); + public Iterable listEdges() { + return () -> + this.vertices + .values() + .stream() + .flatMap(v -> v.getOutgoing().stream()) + .iterator(); } /** - * Return only the StreetEdges in the graph. + * Lazily iterate over all edges of a certain type in the graph, without materializing an + * intermediate collection. Walks the vertices and yielding only the ones that are instances + * of {@code clazz}. + *

+ * The iterable may contain duplicates and can only be iterated once. + *

+ * Note: Under concurrent modification this method may return edges that have been removed from + * the graph or not return edges that have been added to the graph after this method has been + * called. */ - public Collection getStreetEdges() { - return getEdgesOfType(StreetEdge.class); + public Iterable findEdges(Class clazz) { + return StreamSupport.stream(listEdges().spliterator(), false) + .filter(clazz::isInstance) + .map(clazz::cast)::iterator; } public boolean containsVertex(Vertex v) { - return (v != null) && vertices.get(v.getLabel()) == v; + return v != null && vertices.get(v.getLabel()) == v; } public void remove(Vertex vertex) { diff --git a/street/src/main/java/org/opentripplanner/street/graph/summary/GraphSummarizer.java b/street/src/main/java/org/opentripplanner/street/graph/summary/GraphSummarizer.java index ad06ab95c0e..6af7a670ab1 100644 --- a/street/src/main/java/org/opentripplanner/street/graph/summary/GraphSummarizer.java +++ b/street/src/main/java/org/opentripplanner/street/graph/summary/GraphSummarizer.java @@ -28,11 +28,9 @@ public GraphSummarizer(Graph graph) { this.graph = graph; } - /** - * Converts the input to a string-based label and looks it up in the graph. Remember that there - * are other, non-string vertex labels for which this method will not work. - * @see VertexLabel - */ + /// Converts the input to a string-based label and looks it up in the graph. Remember that there + /// are other, non-string vertex labels for which this method will not work. + /// @see VertexLabel @Nullable public Vertex getVertex(String label) { return graph.getVertex(VertexLabel.string(label)); @@ -50,22 +48,24 @@ public List listStopVertices() { return graph.getVerticesOfType(TransitStopVertex.class); } - /** - * Iterates over all vertices in the graph and gets all incoming _and_ outgoing edges. - * This is a different behavior than {@link Graph#getEdges()}, which only returns edges that are - * outgoing. - */ + /// Iterates over all vertices in the graph and gets all incoming _and_ outgoing edges. This is a + /// different behavior than {@link Graph#listEdges()}, which only returns edges that are outgoing. + /// + /// This is needed so that temporary link edges, whose from-vertex is not added to the graph's + /// collection of vertices, are included in the summary and can then be asserted against. public List listEdges() { - return graph - .getVertices() - .stream() - .flatMap(v -> Stream.concat(v.getOutgoing().stream(), v.getIncoming().stream())) - .distinct() - .toList(); + return distinctEdges().toList(); } public List listAreaEdges() { - return graph.getEdgesOfType(AreaEdge.class); + return findEdges(AreaEdge.class); + } + + /** + * Return all edges of a certain type in the graph. + */ + public List findEdges(Class cls) { + return distinctEdges().filter(cls::isInstance).map(cls::cast).toList(); } public String geoJsonUrl() { @@ -99,4 +99,13 @@ public Collection summarizeTempEdges() { public Graph graph() { return graph; } + + /// See [GraphSummarizer#listEdges()] on why both incoming and outgoing edges are returned. + private Stream distinctEdges() { + return graph + .getVertices() + .stream() + .flatMap(v -> Stream.concat(v.getOutgoing().stream(), v.getIncoming().stream())) + .distinct(); + } } diff --git a/street/src/main/java/org/opentripplanner/street/internal/notes/StreetNoteModel.java b/street/src/main/java/org/opentripplanner/street/internal/notes/StreetNoteModel.java deleted file mode 100644 index 3954f87d932..00000000000 --- a/street/src/main/java/org/opentripplanner/street/internal/notes/StreetNoteModel.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.opentripplanner.street.internal.notes; - -import com.google.common.collect.HashMultimap; -import com.google.common.collect.SetMultimap; -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import org.opentripplanner.street.model.edge.Edge; -import org.opentripplanner.street.model.edge.TemporaryPartialStreetEdge; -import org.opentripplanner.street.model.note.StreetNote; -import org.opentripplanner.street.model.note.StreetNoteAndMatcher; -import org.opentripplanner.street.model.note.StreetNoteMatcher; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A notes source of static notes, created at graph building stage and not modified - * thereafter. - */ -public class StreetNoteModel implements Serializable { - - private static final Logger LOG = LoggerFactory.getLogger(StreetNoteModel.class); - - /** - * Notes for street edges. No need to synchronize access to the map as they will not be concurrent - * write access (no notes for temporary edges, we use notes from parent). - */ - private final SetMultimap notesForEdge = HashMultimap.< - Edge, - StreetNoteAndMatcher - >create(); - - /** - * Set of unique matchers, kept during building phase, used for interning (lots of note/matchers - * are identical). - */ - private final transient Map uniqueMatchers = - new HashMap<>(); - - StreetNoteModel() {} - - /** - * Return the set of notes applicable for this state / backedge pair. - * - * @return The set of notes or null if empty. - */ - public Set getNotes(Edge edge) { - /* If the edge is temporary, we look for notes in it's parent edge. */ - if (edge instanceof TemporaryPartialStreetEdge) { - edge = ((TemporaryPartialStreetEdge) edge).getParentEdge(); - } - Set maas = notesForEdge.get(edge); - if (maas == null || maas.isEmpty()) { - return null; - } - return maas; - } - - void addNote(Edge edge, StreetNote note, StreetNoteMatcher matcher) { - if (LOG.isDebugEnabled()) { - LOG.debug("Adding note {} to {} with matcher {}", note, edge, matcher); - } - notesForEdge.put(edge, buildMatcherAndAlert(matcher, note)); - } - - /** - * Remove all notes attached to this edge. NOTE: this should only be called within a graph - * building context (or unit testing). - */ - void removeNotes(Edge edge) { - if (LOG.isDebugEnabled()) { - LOG.debug("Removing notes for edge: {}", edge); - } - notesForEdge.removeAll(edge); - } - - /** - * Create a MatcherAndAlert, interning it if the note and matcher pair is already created. Note: - * we use the default Object.equals() for matchers, as they are mostly already singleton - * instances. - */ - private StreetNoteAndMatcher buildMatcherAndAlert( - StreetNoteMatcher noteMatcher, - StreetNote note - ) { - var candidate = new StreetNoteAndMatcher(note, noteMatcher); - var interned = uniqueMatchers.putIfAbsent(candidate, candidate); - return interned == null ? candidate : interned; - } -} diff --git a/street/src/main/java/org/opentripplanner/street/internal/notes/StreetNotesService.java b/street/src/main/java/org/opentripplanner/street/internal/notes/StreetNotesService.java deleted file mode 100644 index df56f8aa2a4..00000000000 --- a/street/src/main/java/org/opentripplanner/street/internal/notes/StreetNotesService.java +++ /dev/null @@ -1,124 +0,0 @@ -package org.opentripplanner.street.internal.notes; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import org.opentripplanner.street.model.edge.Edge; -import org.opentripplanner.street.model.note.StreetNote; -import org.opentripplanner.street.model.note.StreetNoteAndMatcher; -import org.opentripplanner.street.model.note.StreetNoteMatcher; -import org.opentripplanner.street.search.TraverseMode; -import org.opentripplanner.street.search.state.State; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This service manages street edge notes. An edge note is a free-format alert (text) attached to an - * edge, which is returned along with any itinerary where this edge is used, and which does not - * have any impact on routing. Notes cannot affect routing because edges do not know which notes - * are attached to them. This avoids storing references to notes on the edge, which would probably - * not be worth the memory consumption as only a few edges have notes. - *

- * The service owns a list of StreetNotesSource, with a single static one used for graph building. - * "Dynamic" notes can be returned by classes implementing StreetNoteSource, added to this service - * during startup. - *

- * Typical notes are: Toll (driving), unpaved surface (walk,bike), wheelchair notes... - *

- * Each note is attached to a matcher, whose responsibility is to determine if the note is relevant - * for an edge, based on the itinerary state at this edge (the state after the edge has been - * traversed, ie "state back edge"). Usually matcher will match note based on the mode (cycling, - * driving) or if a wheelchair access is requested. - * - * @author Laurent Grégoire - */ -public class StreetNotesService implements Serializable { - - @SuppressWarnings("unused") - private static final Logger LOG = LoggerFactory.getLogger(StreetNotesService.class); - - public static final StreetNoteMatcher WHEELCHAIR_MATCHER = new StreetNoteMatcher() { - @Override - public boolean matches(State state) { - return state.getRequest().wheelchairEnabled(); - } - }; - - public static final StreetNoteMatcher DRIVING_MATCHER = new StreetNoteMatcher() { - @Override - public boolean matches(State state) { - return state.getBackMode().isDrivingIsh(); - } - }; - - public static final StreetNoteMatcher BICYCLE_MATCHER = new StreetNoteMatcher() { - @Override - public boolean matches(State state) { - return state.getBackMode() == TraverseMode.BICYCLE; - } - }; - - public static final StreetNoteMatcher ALWAYS_MATCHER = new StreetNoteMatcher() { - @Override - public boolean matches(State state) { - return true; - } - }; - - private final List sources = new ArrayList<>(); - - private final StreetNoteModel staticNotesSource = new StreetNoteModel(); - - public StreetNotesService() { - sources.add(staticNotesSource); - } - - /** - * Add a new note source. The list is not transient so any source added before the graph is saved - * will be serialized! - */ - public void addNotesSource(StreetNoteModel source) { - sources.add(source); - } - - /** - * Return the set of notes applicable for this state / backedge pair. - * - * @return The set of notes or null if empty. - */ - public Set getNotes(State state) { - Edge edge = state.getBackEdge(); - Set maas = new HashSet<>(); - - for (StreetNoteModel source : sources) { - Set maas2 = source.getNotes(edge); - if (maas2 != null) { - maas.addAll(maas2); - } - } - if (maas == null || maas.isEmpty()) { - return Set.of(); - } - - Set notes = HashSet.newHashSet(maas.size()); - for (StreetNoteAndMatcher maa : maas) { - if (maa.matcher().matches(state)) { - notes.add(maa.note()); - } - } - if (notes.isEmpty()) { - return Set.of(); - } - return notes; - } - - public void addStaticNote(Edge edge, StreetNote note, StreetNoteMatcher matcher) { - staticNotesSource.addNote(edge, note, matcher); - } - - public void removeStaticNotes(Edge edge) { - staticNotesSource.removeNotes(edge); - } -} diff --git a/street/src/main/java/org/opentripplanner/street/linking/VertexLinker.java b/street/src/main/java/org/opentripplanner/street/linking/VertexLinker.java index fd6f780e3bb..58b0799949b 100644 --- a/street/src/main/java/org/opentripplanner/street/linking/VertexLinker.java +++ b/street/src/main/java/org/opentripplanner/street/linking/VertexLinker.java @@ -199,9 +199,8 @@ private DisposableEdgeCollection link( Scope scope, BiFunction> edgeFunction ) { - DisposableEdgeCollection tempEdges = (scope != Scope.PERMANENT) - ? new DisposableEdgeCollection(graph, scope) - : null; + DisposableEdgeCollection tempEdges = + scope != Scope.PERMANENT ? new DisposableEdgeCollection(graph, scope) : null; try { // Expanding-envelope search: try each radius step (smallest first) and stop at the first that @@ -559,9 +558,10 @@ private SplitterVertex split( // Split the 'edge' at 'v' in 2 new edges and connect these 2 edges to the // existing vertices - var newEdges = scope == Scope.PERMANENT - ? originalEdge.splitDestructively(v) - : originalEdge.splitNonDestructively(v, direction); + var newEdges = + scope == Scope.PERMANENT + ? originalEdge.splitDestructively(v) + : originalEdge.splitNonDestructively(v, direction); if (scope != Scope.PERMANENT) { newEdges.forEach(tempEdges::addEdge); diff --git a/street/src/main/java/org/opentripplanner/street/model/StreetMode.java b/street/src/main/java/org/opentripplanner/street/model/StreetMode.java index fd3c59ef5ec..e8343f9f84a 100644 --- a/street/src/main/java/org/opentripplanner/street/model/StreetMode.java +++ b/street/src/main/java/org/opentripplanner/street/model/StreetMode.java @@ -149,9 +149,9 @@ public String typeDescription() { private static String GBFS_PREREQ = """ - _Prerequisite:_ Vehicle or station locations need to be added to OTP from dynamic data feeds. - See [Configuring GBFS](GBFS-Config.md) on how to add one. - """; + _Prerequisite:_ Vehicle or station locations need to be added to OTP from dynamic data feeds. + See [Configuring GBFS](GBFS-Config.md) on how to add one. + """; @Override public String enumValueDescription() { @@ -172,18 +172,15 @@ public String enumValueDescription() { """; case BIKE_RENTAL -> """ Taking a rented, shared-mobility bike for part or the entirety of the route. - """ + - GBFS_PREREQ; + """ + GBFS_PREREQ; case SCOOTER_RENTAL -> """ Walking to a scooter rental point, riding a scooter to a scooter rental drop-off point, and walking the rest of the way. This can include scooter rental at fixed locations or free-floating services. - """ + - GBFS_PREREQ; + """ + GBFS_PREREQ; case CAR_RENTAL -> """ Walk to a car rental point, drive to a car rental drop-off point and walk the rest of the way. This can include car rental at fixed locations or free-floating services. - """ + - GBFS_PREREQ; + """ + GBFS_PREREQ; case CAR -> """ Driving your own car the entirety of the route. This can be combined with transit, where will return routes with a [Kiss & Ride](https://en.wikipedia.org/wiki/Park_and_ride#Kiss_and_ride_/_kiss_and_fly) component. diff --git a/street/src/main/java/org/opentripplanner/street/model/edge/CarPickupableEdge.java b/street/src/main/java/org/opentripplanner/street/model/edge/CarPickupableEdge.java index 75fdab145f0..a5f6d009e37 100644 --- a/street/src/main/java/org/opentripplanner/street/model/edge/CarPickupableEdge.java +++ b/street/src/main/java/org/opentripplanner/street/model/edge/CarPickupableEdge.java @@ -9,9 +9,9 @@ default boolean canPickupAndDrive(State state) { return ( state.getRequest().mode().includesPickup() && state.getCarPickupState() == - (state.getRequest().arriveBy() - ? CarPickupState.WALK_FROM_DROP_OFF - : CarPickupState.WALK_TO_PICKUP) + (state.getRequest().arriveBy() + ? CarPickupState.WALK_FROM_DROP_OFF + : CarPickupState.WALK_TO_PICKUP) ); } diff --git a/street/src/main/java/org/opentripplanner/street/model/edge/Edge.java b/street/src/main/java/org/opentripplanner/street/model/edge/Edge.java index a033bcd9aa3..b8def7cd5cc 100644 --- a/street/src/main/java/org/opentripplanner/street/model/edge/Edge.java +++ b/street/src/main/java/org/opentripplanner/street/model/edge/Edge.java @@ -4,7 +4,6 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; -import java.util.Objects; import java.util.function.Consumer; import javax.annotation.Nullable; import org.locationtech.jts.geom.LineString; @@ -56,14 +55,6 @@ public final Vertex getToVertex() { return tov; } - /** - * Checks equivalency to another edge. Default implementation is trivial equality, but subclasses - * may want to do something more tricky. - */ - public boolean isEquivalentTo(Edge e) { - return this == e; - } - /** * Returns true if this edge is the reverse of another. */ @@ -99,16 +90,22 @@ public boolean isReachableFromGraph() { return edgeReachableFromGraph; } + /** + * Returns the identity hash code of this edge. Edges use object identity for equality, so the + * hash code is based on memory location rather than content. See {@link #equals(Object)}. + */ @Override - public int hashCode() { - return Objects.hash(fromv, tov); + public final int hashCode() { + return System.identityHashCode(this); } /** - * Implementing equals methods for edges is complicated. Implementing this to match the hashCode - * method causes problems. Leaving this comment here in case it helps someone in the future. + * Edges use object identity (reference equality) for {@code equals} and {@code hashCode}. + * This makes edge lookups in sets and maps efficient and avoids ambiguity during graph + * construction, where structurally similar edges may coexist. *

- * TODO figure out equals method for edges, e.g. unique long/int for each edge + * Do not use this method to test whether two edges represent the same street segment + * or share the same content. */ @Override public boolean equals(Object o) { diff --git a/street/src/main/java/org/opentripplanner/street/model/edge/ElevatorHopEdge.java b/street/src/main/java/org/opentripplanner/street/model/edge/ElevatorHopEdge.java index d4a84c73f76..8c8855b3ae0 100644 --- a/street/src/main/java/org/opentripplanner/street/model/edge/ElevatorHopEdge.java +++ b/street/src/main/java/org/opentripplanner/street/model/edge/ElevatorHopEdge.java @@ -26,6 +26,7 @@ public class ElevatorHopEdge extends Edge implements ElevatorEdge, WheelchairTra private final double levels; private final int travelTime; + private final String id; private ElevatorHopEdge( Vertex from, @@ -33,13 +34,15 @@ private ElevatorHopEdge( StreetTraversalPermission permission, Accessibility wheelchairAccessibility, double levels, - int travelTime + int travelTime, + String id ) { super(from, to); this.permission = permission; this.wheelchairAccessibility = wheelchairAccessibility; this.levels = levels; this.travelTime = travelTime; + this.id = id; } private ElevatorHopEdge( @@ -48,7 +51,7 @@ private ElevatorHopEdge( StreetTraversalPermission permission, Accessibility wheelchairAccessibility ) { - this(from, to, permission, wheelchairAccessibility, DEFAULT_LEVELS, DEFAULT_TRAVEL_TIME); + this(from, to, permission, wheelchairAccessibility, DEFAULT_LEVELS, DEFAULT_TRAVEL_TIME, null); } public static void bidirectional( @@ -57,10 +60,11 @@ public static void bidirectional( StreetTraversalPermission permission, Accessibility wheelchairBoarding, double levels, - int travelTime + int travelTime, + String id ) { - createElevatorHopEdge(from, to, permission, wheelchairBoarding, levels, travelTime); - createElevatorHopEdge(to, from, permission, wheelchairBoarding, levels, travelTime); + createElevatorHopEdge(from, to, permission, wheelchairBoarding, levels, travelTime, id); + createElevatorHopEdge(to, from, permission, wheelchairBoarding, levels, travelTime, id); } public static ElevatorHopEdge createElevatorHopEdge( @@ -70,9 +74,29 @@ public static ElevatorHopEdge createElevatorHopEdge( Accessibility wheelchairAccessibility, double levels, int travelTime + ) { + return createElevatorHopEdge( + from, + to, + permission, + wheelchairAccessibility, + levels, + travelTime, + null + ); + } + + private static ElevatorHopEdge createElevatorHopEdge( + Vertex from, + Vertex to, + StreetTraversalPermission permission, + Accessibility wheelchairAccessibility, + double levels, + int travelTime, + String id ) { return connectToGraph( - new ElevatorHopEdge(from, to, permission, wheelchairAccessibility, levels, travelTime) + new ElevatorHopEdge(from, to, permission, wheelchairAccessibility, levels, travelTime, id) ); } @@ -89,6 +113,17 @@ public StreetTraversalPermission getPermission() { return permission; } + /** + * The id of the elevator, as extracted from OSM tags configured via the + * {@code elevatorRefTags} build-config option. Will be used for #6533. + *

+ * If multiple configured tag groups resolve to a value, the first one (in configured order) + * is used. + */ + public Optional id() { + return Optional.ofNullable(id); + } + /** * The number of levels that the ElevatorHopEdge travels. */ @@ -148,9 +183,10 @@ public State[] traverse(State s0) { // // X ElevatorHopVertex // --- ElevatorHopEdge - int time = this.travelTime > 0 - ? this.travelTime - : (int) (request.elevator().hopTime().toSeconds() * this.levels); + int time = + this.travelTime > 0 + ? this.travelTime + : (int) (request.elevator().hopTime().toSeconds() * this.levels); s1.incrementWeight(request.elevator().reluctance() * time); s1.incrementTimeInSeconds(time); return s1.makeStateArray(); diff --git a/street/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java b/street/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java index 5c4d8ed63a0..601983c51bb 100644 --- a/street/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java +++ b/street/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java @@ -38,7 +38,8 @@ */ public class StreetEdge extends Edge - implements BikeWalkableEdge, Cloneable, CarPickupableEdge, WheelchairTraversalInformation { + implements BikeWalkableEdge, Cloneable, CarPickupableEdge, WheelchairTraversalInformation +{ private static final Logger LOG = LoggerFactory.getLogger(StreetEdge.class); @@ -214,7 +215,7 @@ public double calculateSpeed( case FLEX -> throw new IllegalArgumentException("getSpeed(): Invalid mode " + traverseMode); }; - return isStairs() ? (speed / preferences.walk().stairsTimeFactor()) : speed; + return isStairs() ? speed / preferences.walk().stairsTimeFactor() : speed; } /** @@ -705,9 +706,8 @@ protected void copyPropertiesToSplitEdge( seb.withWalkSafetyFactor(walkSafetyFactor); seb.withCarSpeed(carSpeed); - var partialElevationProfileFromParent = elevationExtension != null - ? elevationExtension.partial(fromDistance, toDistance) - : null; + var partialElevationProfileFromParent = + elevationExtension != null ? elevationExtension.partial(fromDistance, toDistance) : null; StreetElevationExtensionBuilder.of(seb) .withDistanceInMeters(defaultMillimeterLength(seb.geometry()) / 1000.) @@ -730,8 +730,10 @@ private int computeLength(StreetEdgeBuilder builder) { : builder.millimeterLength(); if ( lengthInMillimeter == 0 && - !(getFromVertex() instanceof BarrierPassThroughVertex || - getToVertex() instanceof BarrierPassThroughVertex) + !( + getFromVertex() instanceof BarrierPassThroughVertex || + getToVertex() instanceof BarrierPassThroughVertex + ) ) { LOG.warn( "StreetEdge {} from {} to {} has length of 0. This is usually an error.", @@ -935,9 +937,8 @@ private TraversalCosts bicycleOrScooterTraversalCost( double time = effectiveTimeDistance / speed; double weight; - var optimizeType = mode == TraverseMode.BICYCLE - ? req.bike().optimizeType() - : req.scooter().optimizeType(); + var optimizeType = + mode == TraverseMode.BICYCLE ? req.bike().optimizeType() : req.scooter().optimizeType(); switch (optimizeType) { case SAFE_STREETS -> weight = getEffectiveBicycleSafetyDistance() / speed; case FLAT_STREETS -> @@ -951,9 +952,10 @@ private TraversalCosts bicycleOrScooterTraversalCost( propulsion, electricAssistSlopeSensitivity ); - var triangle = mode == TraverseMode.BICYCLE - ? req.bike().optimizeTriangle() - : req.scooter().optimizeTriangle(); + var triangle = + mode == TraverseMode.BICYCLE + ? req.bike().optimizeTriangle() + : req.scooter().optimizeTriangle(); weight = quick * triangle.time() + slope * triangle.slope() + safety * triangle.safety(); weight /= speed; } @@ -1041,7 +1043,7 @@ private TraversalCosts walkingTraversalCosts( } else { if (walkingBike) { // take slopes into account when walking bikes - time = weight = (getEffectiveBikeDistance() / speed); + time = weight = getEffectiveBikeDistance() / speed; } else { // take slopes into account when walking time = getEffectiveWalkDistance() / speed; diff --git a/street/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java b/street/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java index 7cb401fb2a8..1c53e698630 100644 --- a/street/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java +++ b/street/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java @@ -66,7 +66,7 @@ static double computeWheelchairReluctance( double slopeExceededReluctance = wheelchair.slopeExceededReluctance(); if (slopeExceededReluctance > 0.0) { // if we exceed the max slope the cost increases multiplied by how much you go over the maxSlope - reluctance *= 1.0 + (100.0 * slopeExceededBy) * slopeExceededReluctance; + reluctance *= 1.0 + 100.0 * slopeExceededBy * slopeExceededReluctance; } } return reluctance; diff --git a/street/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java b/street/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java index d1f12d813ef..5f681898902 100644 --- a/street/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java +++ b/street/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java @@ -15,7 +15,8 @@ */ public abstract class StreetTransitEntityLink extends Edge - implements CarPickupableEdge { + implements CarPickupableEdge +{ static final int STEL_TRAVERSE_COST = 1; @@ -88,11 +89,13 @@ public State[] traverse(State s0) { // floating rental vehicles. else if ( s0.isRentingVehicleFromStation() && - !(s0.mayKeepRentedVehicleAtDestination() && + !( + s0.mayKeepRentedVehicleAtDestination() && s0 .getRequest() .rental(s0.getRequest().mode()) - .allowArrivingInRentedVehicleAtDestination()) + .allowArrivingInRentedVehicleAtDestination() + ) ) { yield State.empty(); } diff --git a/street/src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdge.java b/street/src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdge.java index 3c19e7ab69d..ed187d1c193 100644 --- a/street/src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdge.java +++ b/street/src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdge.java @@ -25,15 +25,6 @@ public final class TemporaryPartialStreetEdge extends StreetEdge implements Temp this.geometry = super.getGeometry(); } - /** - * This implementation makes it so that TurnRestrictions on the parent edge are applied to this - * edge as well. - */ - @Override - public boolean isEquivalentTo(Edge e) { - return (e == this || e == parentEdge); - } - /** * Returns true if this edge is trivial - beginning and ending at the same point. */ diff --git a/street/src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeBuilder.java b/street/src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeBuilder.java index 2f9bb969cbc..f0ce8485291 100644 --- a/street/src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeBuilder.java +++ b/street/src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeBuilder.java @@ -1,7 +1,8 @@ package org.opentripplanner.street.model.edge; public class TemporaryPartialStreetEdgeBuilder - extends StreetEdgeBuilder { + extends StreetEdgeBuilder +{ private StreetEdge parentEdge; diff --git a/street/src/main/java/org/opentripplanner/street/model/elevation/BicycleSlopeSpeedFunction.java b/street/src/main/java/org/opentripplanner/street/model/elevation/BicycleSlopeSpeedFunction.java index 759c3363d43..4da427617b9 100644 --- a/street/src/main/java/org/opentripplanner/street/model/elevation/BicycleSlopeSpeedFunction.java +++ b/street/src/main/java/org/opentripplanner/street/model/elevation/BicycleSlopeSpeedFunction.java @@ -119,7 +119,7 @@ public static double coefficient(double slope, double altitude) { int l = kx1; int l1 = l + 1; - while ((altitude >= TX[l1 - 1]) && (l != nkx1)) { + while (altitude >= TX[l1 - 1] && l != nkx1) { l = l1; l1 = l + 1; } @@ -153,7 +153,7 @@ public static double coefficient(double slope, double altitude) { l = ky1; l1 = l + 1; - while ((slope >= TY[l1 - 1]) && (l != nky1)) { + while (slope >= TY[l1 - 1] && l != nky1) { l = l1; l1 = l + 1; } diff --git a/street/src/main/java/org/opentripplanner/street/model/note/StreetNote.java b/street/src/main/java/org/opentripplanner/street/model/note/StreetNote.java deleted file mode 100644 index 9af2139d47c..00000000000 --- a/street/src/main/java/org/opentripplanner/street/model/note/StreetNote.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.opentripplanner.street.model.note; - -import java.io.Serializable; -import java.util.Date; -import java.util.Objects; -import org.opentripplanner.core.model.i18n.I18NString; -import org.opentripplanner.core.model.i18n.NonLocalizedString; - -public class StreetNote implements Serializable { - - public final I18NString note; - public I18NString descriptionText; - public Date effectiveStartDate; - public Date effectiveEndDate; - public String url; - - public StreetNote(I18NString note) { - this.note = note; - } - - public StreetNote(String note) { - this.note = new NonLocalizedString(note); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - StreetNote that = (StreetNote) o; - return ( - Objects.equals(note, that.note) && - Objects.equals(descriptionText, that.descriptionText) && - Objects.equals(effectiveStartDate, that.effectiveStartDate) && - Objects.equals(effectiveEndDate, that.effectiveEndDate) && - Objects.equals(url, that.url) - ); - } - - @Override - public int hashCode() { - return Objects.hash(note, descriptionText, effectiveStartDate, effectiveEndDate, url); - } -} diff --git a/street/src/main/java/org/opentripplanner/street/model/note/StreetNoteAndMatcher.java b/street/src/main/java/org/opentripplanner/street/model/note/StreetNoteAndMatcher.java deleted file mode 100644 index ed99847ee8c..00000000000 --- a/street/src/main/java/org/opentripplanner/street/model/note/StreetNoteAndMatcher.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.opentripplanner.street.model.note; - -import java.io.Serializable; -import java.util.Objects; -import org.opentripplanner.utils.tostring.ToStringBuilder; - -/** - * A container for a pair (note and note matcher). - * - * @author laurent - */ -@SuppressWarnings("ClassCanBeRecord") -public class StreetNoteAndMatcher implements Serializable { - - private final StreetNote note; - private final StreetNoteMatcher matcher; - - public StreetNoteAndMatcher(StreetNote note, StreetNoteMatcher matcher) { - this.matcher = matcher; - this.note = note; - } - - public StreetNoteMatcher matcher() { - return matcher; - } - - public StreetNote note() { - return note; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - StreetNoteAndMatcher that = (StreetNoteAndMatcher) o; - return note.equals(that.note) && matcher.equals(that.matcher); - } - - @Override - public int hashCode() { - return Objects.hash(note, matcher); - } - - @Override - public String toString() { - return ToStringBuilder.of(StreetNoteAndMatcher.class) - .addObj("note", note) - .addObj("matcher", matcher) - .toString(); - } -} diff --git a/street/src/main/java/org/opentripplanner/street/model/note/StreetNoteMatcher.java b/street/src/main/java/org/opentripplanner/street/model/note/StreetNoteMatcher.java deleted file mode 100644 index 9b9a0285128..00000000000 --- a/street/src/main/java/org/opentripplanner/street/model/note/StreetNoteMatcher.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.opentripplanner.street.model.note; - -import java.io.Serializable; -import org.opentripplanner.street.search.state.State; - -/** - * A note matcher will determine if a note is applicable to a given state, based on condition such - * as current traverse mode, wheelchair access, etc... - * - * @author laurent - */ -public interface StreetNoteMatcher extends Serializable { - boolean matches(State state); -} diff --git a/street/src/main/java/org/opentripplanner/street/model/openinghours/OHCalendarBuilder.java b/street/src/main/java/org/opentripplanner/street/model/openinghours/OHCalendarBuilder.java index 3844e0c5975..3ac794c66dc 100644 --- a/street/src/main/java/org/opentripplanner/street/model/openinghours/OHCalendarBuilder.java +++ b/street/src/main/java/org/opentripplanner/street/model/openinghours/OHCalendarBuilder.java @@ -131,9 +131,8 @@ public OpeningHoursBuilder on(DayOfWeek dayOfWeek) { // when the specified dayOfWeek occurs for the first time. int rawWeekDayDifference = shiftedDayOfWeek.getValue() - startOfPeriod.getDayOfWeek().getValue(); - int firstOccurrenceDaysFromStart = rawWeekDayDifference >= 0 - ? rawWeekDayDifference - : 7 - Math.abs(rawWeekDayDifference); + int firstOccurrenceDaysFromStart = + rawWeekDayDifference >= 0 ? rawWeekDayDifference : 7 - Math.abs(rawWeekDayDifference); for (int i = firstOccurrenceDaysFromStart; i < daysInPeriod; i += 7) { openingDays.set(i); @@ -155,9 +154,10 @@ public OpeningHoursBuilder on(DayOfWeek fromDayOfWeek, DayOfWeek untilDayOfWeek) return this; } - int untilAdjusted = fromDayOfWeek.getValue() > untilDayOfWeek.getValue() - ? untilDayOfWeek.getValue() + 7 - : untilDayOfWeek.getValue(); + int untilAdjusted = + fromDayOfWeek.getValue() > untilDayOfWeek.getValue() + ? untilDayOfWeek.getValue() + 7 + : untilDayOfWeek.getValue(); for (int i = fromDayOfWeek.getValue(); i <= untilAdjusted; i++) { int dayValue = i > 7 ? i - 7 : i; on(DayOfWeek.of(dayValue)); @@ -185,9 +185,10 @@ public OpeningHoursBuilder on( if (untilMonth == null) { months.add(fromMonth); } else { - int untilMonthAdjusted = fromMonth.getValue() > untilMonth.getValue() - ? untilMonth.getValue() + 12 - : untilMonth.getValue(); + int untilMonthAdjusted = + fromMonth.getValue() > untilMonth.getValue() + ? untilMonth.getValue() + 12 + : untilMonth.getValue(); for (int i = fromMonth.getValue(); i <= untilMonthAdjusted; i++) { int monthValue = i > 12 ? i - 12 : i; months.add(Month.of(monthValue)); @@ -198,9 +199,10 @@ public OpeningHoursBuilder on( if (untilDayOfWeek == null) { daysOfWeek.add(fromDayOfWeek); } else { - int untilDayAdjusted = fromDayOfWeek.getValue() > untilDayOfWeek.getValue() - ? untilDayOfWeek.getValue() + 7 - : untilDayOfWeek.getValue(); + int untilDayAdjusted = + fromDayOfWeek.getValue() > untilDayOfWeek.getValue() + ? untilDayOfWeek.getValue() + 7 + : untilDayOfWeek.getValue(); for (int i = fromDayOfWeek.getValue(); i <= untilDayAdjusted; i++) { int dayValue = i > 7 ? i - 7 : i; daysOfWeek.add(DayOfWeek.of(dayValue)); @@ -296,7 +298,7 @@ public OpeningHoursBuilderAndNewBuilders createBuildersForRelativeComplement( String offDescription = otherBuilder.getPeriodDescription(); if ( (otherStartTime.isBefore(startTime) || otherStartTime.equals(startTime)) && - ((endTime.isBefore(otherEndTime) || endTime.equals(otherEndTime))) + (endTime.isBefore(otherEndTime) || endTime.equals(otherEndTime)) ) { off(otherBuilder.getOpeningDays(), offDescription); return new OpeningHoursBuilderAndNewBuilders(this, List.of()); diff --git a/street/src/main/java/org/opentripplanner/street/model/vertex/BarrierVertex.java b/street/src/main/java/org/opentripplanner/street/model/vertex/BarrierVertex.java index 694a4971d0f..c94790d45fb 100644 --- a/street/src/main/java/org/opentripplanner/street/model/vertex/BarrierVertex.java +++ b/street/src/main/java/org/opentripplanner/street/model/vertex/BarrierVertex.java @@ -62,8 +62,7 @@ public void makeBarrierAtEndReachable() { out.isEmpty() || in.isEmpty() || // in+out edge pair connects the vertex to a single adjacent vertex -> must be street end point - out.iterator().next().getToVertex() == - in.iterator().next().getFromVertex() + out.iterator().next().getToVertex() == in.iterator().next().getFromVertex() ) { needsFix = true; } diff --git a/street/src/main/java/org/opentripplanner/street/model/vertex/OsmBoardingLocationVertex.java b/street/src/main/java/org/opentripplanner/street/model/vertex/OsmBoardingLocationVertex.java index e0d695caf86..c9e2406dba7 100644 --- a/street/src/main/java/org/opentripplanner/street/model/vertex/OsmBoardingLocationVertex.java +++ b/street/src/main/java/org/opentripplanner/street/model/vertex/OsmBoardingLocationVertex.java @@ -40,7 +40,7 @@ public String toString() { } public boolean isConnectedToStreetNetwork() { - return (getOutgoing().size() + getIncoming().size()) > 0; + return getOutgoing().size() + getIncoming().size() > 0; } @Override diff --git a/street/src/main/java/org/opentripplanner/street/model/vertex/Vertex.java b/street/src/main/java/org/opentripplanner/street/model/vertex/Vertex.java index 0ea40b49ea5..4837b90d118 100644 --- a/street/src/main/java/org/opentripplanner/street/model/vertex/Vertex.java +++ b/street/src/main/java/org/opentripplanner/street/model/vertex/Vertex.java @@ -84,7 +84,7 @@ public boolean removeOutgoing(Edge edge) { synchronized (this) { int n = outgoing.length; outgoing = removeEdge(outgoing, edge); - return (outgoing.length < n); + return outgoing.length < n; } } @@ -99,7 +99,7 @@ public boolean removeIncoming(Edge edge) { synchronized (this) { int n = incoming.length; incoming = removeEdge(incoming, edge); - return (incoming.length < n); + return incoming.length < n; } } diff --git a/street/src/main/java/org/opentripplanner/street/model/vertex/VertexLabel.java b/street/src/main/java/org/opentripplanner/street/model/vertex/VertexLabel.java index 224b59af805..b5a09ea7d62 100644 --- a/street/src/main/java/org/opentripplanner/street/model/vertex/VertexLabel.java +++ b/street/src/main/java/org/opentripplanner/street/model/vertex/VertexLabel.java @@ -61,8 +61,11 @@ public String toString() { *

* Used for elevator vertices and split vertices. */ - record VertexWithEntityLabel(long nodeId, OsmEntityType osmEntityType, long entityId) implements - VertexLabel { + record VertexWithEntityLabel( + long nodeId, + OsmEntityType osmEntityType, + long entityId + ) implements VertexLabel { private static final String TEMPLATE = "osm:node:%s:%s:%s"; @Override diff --git a/street/src/main/java/org/opentripplanner/street/search/intersection_model/AbstractIntersectionTraversalCalculator.java b/street/src/main/java/org/opentripplanner/street/search/intersection_model/AbstractIntersectionTraversalCalculator.java index 06fa79c9fc5..3e31fb3c2ed 100644 --- a/street/src/main/java/org/opentripplanner/street/search/intersection_model/AbstractIntersectionTraversalCalculator.java +++ b/street/src/main/java/org/opentripplanner/street/search/intersection_model/AbstractIntersectionTraversalCalculator.java @@ -10,7 +10,8 @@ * @author avi */ public abstract class AbstractIntersectionTraversalCalculator - implements IntersectionTraversalCalculator { + implements IntersectionTraversalCalculator +{ /** Factor by which absolute turn angles are divided to get turn durations for non-driving scenarios. */ protected double nonDrivingTurnDurationFactor = 1.0 / 20.0; diff --git a/street/src/main/java/org/opentripplanner/street/search/intersection_model/ConstantIntersectionTraversalCalculator.java b/street/src/main/java/org/opentripplanner/street/search/intersection_model/ConstantIntersectionTraversalCalculator.java index 19d28419977..d4c678443e4 100644 --- a/street/src/main/java/org/opentripplanner/street/search/intersection_model/ConstantIntersectionTraversalCalculator.java +++ b/street/src/main/java/org/opentripplanner/street/search/intersection_model/ConstantIntersectionTraversalCalculator.java @@ -8,7 +8,8 @@ * The duration of traversing an intersection is constant. */ public class ConstantIntersectionTraversalCalculator - extends AbstractIntersectionTraversalCalculator { + extends AbstractIntersectionTraversalCalculator +{ private final double duration; diff --git a/street/src/main/java/org/opentripplanner/street/search/intersection_model/SimpleIntersectionTraversalCalculator.java b/street/src/main/java/org/opentripplanner/street/search/intersection_model/SimpleIntersectionTraversalCalculator.java index 27a64b11ad7..beeabc07891 100644 --- a/street/src/main/java/org/opentripplanner/street/search/intersection_model/SimpleIntersectionTraversalCalculator.java +++ b/street/src/main/java/org/opentripplanner/street/search/intersection_model/SimpleIntersectionTraversalCalculator.java @@ -8,7 +8,8 @@ public class SimpleIntersectionTraversalCalculator extends AbstractIntersectionTraversalCalculator - implements Serializable { + implements Serializable +{ private final DrivingDirection drivingDirection; diff --git a/street/src/main/java/org/opentripplanner/street/search/request/EscalatorRequest.java b/street/src/main/java/org/opentripplanner/street/search/request/EscalatorRequest.java index 335900b1ce1..49aac65805b 100644 --- a/street/src/main/java/org/opentripplanner/street/search/request/EscalatorRequest.java +++ b/street/src/main/java/org/opentripplanner/street/search/request/EscalatorRequest.java @@ -53,7 +53,7 @@ public boolean equals(Object o) { return false; } EscalatorRequest that = (EscalatorRequest) o; - return (doubleEquals(that.reluctance, reluctance) && doubleEquals(that.speed, speed)); + return doubleEquals(that.reluctance, reluctance) && doubleEquals(that.speed, speed); } @Override diff --git a/street/src/main/java/org/opentripplanner/street/search/request/WheelchairRequest.java b/street/src/main/java/org/opentripplanner/street/search/request/WheelchairRequest.java index aeffb1269d1..4b51f545c5a 100644 --- a/street/src/main/java/org/opentripplanner/street/search/request/WheelchairRequest.java +++ b/street/src/main/java/org/opentripplanner/street/search/request/WheelchairRequest.java @@ -212,7 +212,8 @@ public Builder withElevator(AccessibilityRequest elevator) { } public Builder withElevator(Consumer body) { - this.elevator = this.elevator.copyOfWithDefaultCosts(DEFAULT_ELEVATOR_PREFERENCES) + this.elevator = this.elevator + .copyOfWithDefaultCosts(DEFAULT_ELEVATOR_PREFERENCES) .apply(body) .build(); return this; diff --git a/street/src/main/java/org/opentripplanner/street/search/request/filter/ParkingFilter.java b/street/src/main/java/org/opentripplanner/street/search/request/filter/ParkingFilter.java index baa559deb5c..5c0cf2bd6e3 100644 --- a/street/src/main/java/org/opentripplanner/street/search/request/filter/ParkingFilter.java +++ b/street/src/main/java/org/opentripplanner/street/search/request/filter/ParkingFilter.java @@ -77,7 +77,7 @@ public boolean equals(Object o) { return false; } ParkingFilter that = (ParkingFilter) o; - return (Arrays.equals(not, that.not) && Arrays.equals(select, that.select)); + return Arrays.equals(not, that.not) && Arrays.equals(select, that.select); } @Override diff --git a/street/src/main/java/org/opentripplanner/street/search/state/State.java b/street/src/main/java/org/opentripplanner/street/search/state/State.java index d2ff35f7107..7d294639484 100644 --- a/street/src/main/java/org/opentripplanner/street/search/state/State.java +++ b/street/src/main/java/org/opentripplanner/street/search/state/State.java @@ -220,7 +220,7 @@ public boolean isCompatibleVehicleRentalState(State state) { return ( stateData.vehicleRentalState == state.stateData.vehicleRentalState && stateData.mayKeepRentedVehicleAtDestination == - state.stateData.mayKeepRentedVehicleAtDestination + state.stateData.mayKeepRentedVehicleAtDestination ); } @@ -276,8 +276,7 @@ public boolean isFinal() { vehicleParkAndRideOk = !parkAndRide || !isVehicleParked(); } else { vehicleRentingOk = - !request.mode().includesRenting() || - (vehicleRentalNotStarted() || vehicleRentalIsFinished()); + !request.mode().includesRenting() || vehicleRentalNotStarted() || vehicleRentalIsFinished(); vehicleParkAndRideOk = !parkAndRide || isVehicleParked(); } return vehicleRentingOk && vehicleParkAndRideOk; @@ -407,7 +406,7 @@ public State reverse() { ); } } else if (!orig.isRentingVehicle() && orig.getBackState().isRentingVehicle()) { - var stationVertex = ((VehicleRentalPlaceVertex) orig.vertex); + var stationVertex = (VehicleRentalPlaceVertex) orig.vertex; if (orig.getBackState().isRentingVehicleFromStation()) { editor.beginVehicleRentingAtStation( ((VehicleRentalEdge) edge).formFactor, diff --git a/street/src/main/java/org/opentripplanner/street/search/state/StateEditor.java b/street/src/main/java/org/opentripplanner/street/search/state/StateEditor.java index 93af5b74a2f..a28b8dd7c9f 100644 --- a/street/src/main/java/org/opentripplanner/street/search/state/StateEditor.java +++ b/street/src/main/java/org/opentripplanner/street/search/state/StateEditor.java @@ -101,7 +101,7 @@ public State makeState() { // check that time changes are coherent with edge traversal // direction double timeDelta = time_ms - backState.getTimeMilliseconds(); - if (traversingBackward ? (timeDelta > 0) : (timeDelta < 0)) { + if (traversingBackward ? timeDelta > 0 : timeDelta < 0) { throw new IllegalStateException( "Time was incremented the wrong direction during state editing, while traversing " + backEdge @@ -160,7 +160,7 @@ public void incrementTimeInMilliseconds(long milliseconds) { "A state's time is being incremented by a negative amount while traversing edge " + backEdge ); } - this.time_ms += (traversingBackward ? -milliseconds : milliseconds); + this.time_ms += traversingBackward ? -milliseconds : milliseconds; } public void incrementTimeInSeconds(long seconds) { @@ -368,9 +368,10 @@ public void dropFloatingVehicle( if (reverse) { stateData.mayKeepRentedVehicleAtDestination = false; stateData.vehicleRentalState = VehicleRentalState.RENTING_FLOATING; - stateData.currentMode = formFactor != null - ? formFactor.traverseMode - : StreetModeToRentalTraverseModeMapper.map(request.mode()); + stateData.currentMode = + formFactor != null + ? formFactor.traverseMode + : StreetModeToRentalTraverseModeMapper.map(request.mode()); stateData.vehicleRentalNetwork = network; stateData.rentalVehicleFormFactor = formFactor; stateData.rentalVehiclePropulsionType = propulsionType; diff --git a/street/src/main/java/org/opentripplanner/street/search/strategy/DominanceFunctions.java b/street/src/main/java/org/opentripplanner/street/search/strategy/DominanceFunctions.java index 704cbf45854..73d1fa1e58a 100644 --- a/street/src/main/java/org/opentripplanner/street/search/strategy/DominanceFunctions.java +++ b/street/src/main/java/org/opentripplanner/street/search/strategy/DominanceFunctions.java @@ -93,7 +93,7 @@ public boolean betterOrEqualAndComparable(State a, State b) { */ if ( a.backEdge != b.getBackEdge() && - (a.backEdge instanceof StreetEdge) && + a.backEdge instanceof StreetEdge && a.getBackMode() != null && a.getBackMode().isDrivingIsh() && a.getRequest().isCloseToStartOrEnd(a.getVertex()) @@ -163,8 +163,8 @@ public boolean betterOrEqual(State a, State b) { final double EPSILON = 1e-4; return ( - a.getElapsedTimeSeconds() <= (b.getElapsedTimeSeconds() + EPSILON) && - a.getWeight() <= (b.getWeight() + EPSILON) + a.getElapsedTimeSeconds() <= b.getElapsedTimeSeconds() + EPSILON && + a.getWeight() <= b.getWeight() + EPSILON ); } } diff --git a/street/src/test-fixtures/java/org/opentripplanner/street/geometry/Polygons.java b/street/src/test-fixtures/java/org/opentripplanner/street/geometry/Polygons.java index 0d529e2b0c4..4b370b8c32e 100644 --- a/street/src/test-fixtures/java/org/opentripplanner/street/geometry/Polygons.java +++ b/street/src/test-fixtures/java/org/opentripplanner/street/geometry/Polygons.java @@ -8,40 +8,36 @@ public class Polygons { private static final GeometryFactory FAC = GeometryUtils.getGeometryFactory(); - public static final Polygon OSLO = FAC.createPolygon( - new Coordinate[] { - new Coordinate(10.62535658370308, 59.961055202323195), - new Coordinate(10.62535658370308, 59.889009435700416), - new Coordinate(10.849791142928694, 59.889009435700416), - new Coordinate(10.849791142928694, 59.961055202323195), - new Coordinate(10.62535658370308, 59.961055202323195), - } - ); + public static final Polygon OSLO = FAC.createPolygon(new Coordinate[] { + new Coordinate(10.62535658370308, 59.961055202323195), + new Coordinate(10.62535658370308, 59.889009435700416), + new Coordinate(10.849791142928694, 59.889009435700416), + new Coordinate(10.849791142928694, 59.961055202323195), + new Coordinate(10.62535658370308, 59.961055202323195), + }); - public static final Polygon OSLO_FROGNER_PARK = FAC.createPolygon( - new Coordinate[] { - new Coordinate(10.69770054003061, 59.92939032560119), - new Coordinate(10.695210909925208, 59.929138466684975), - new Coordinate(10.692696865071184, 59.92745319808358), - new Coordinate(10.693774304996225, 59.92709930323093), - new Coordinate(10.69495957972947, 59.92745914988427), - new Coordinate(10.697664535925895, 59.92736919590291), - new Coordinate(10.697927604125255, 59.924837887427856), - new Coordinate(10.697448767354985, 59.924447953413335), - new Coordinate(10.697819761729818, 59.92378800804022), - new Coordinate(10.699196446969069, 59.92329018587293), - new Coordinate(10.700285749621997, 59.92347619027632), - new Coordinate(10.704714696822037, 59.92272030268688), - new Coordinate(10.71001707489603, 59.92597766029715), - new Coordinate(10.707838597058043, 59.92676341291536), - new Coordinate(10.708389137506913, 59.92790300889098), - new Coordinate(10.707060536853078, 59.928376832499424), - new Coordinate(10.705803789539402, 59.92831087551576), - new Coordinate(10.706641515204467, 59.92953431964068), - new Coordinate(10.70484606360543, 59.93046383654274), - new Coordinate(10.701817874860211, 59.93008590667682), - new Coordinate(10.700525251174469, 59.93028982601595), - new Coordinate(10.69770054003061, 59.92939032560119), - } - ); + public static final Polygon OSLO_FROGNER_PARK = FAC.createPolygon(new Coordinate[] { + new Coordinate(10.69770054003061, 59.92939032560119), + new Coordinate(10.695210909925208, 59.929138466684975), + new Coordinate(10.692696865071184, 59.92745319808358), + new Coordinate(10.693774304996225, 59.92709930323093), + new Coordinate(10.69495957972947, 59.92745914988427), + new Coordinate(10.697664535925895, 59.92736919590291), + new Coordinate(10.697927604125255, 59.924837887427856), + new Coordinate(10.697448767354985, 59.924447953413335), + new Coordinate(10.697819761729818, 59.92378800804022), + new Coordinate(10.699196446969069, 59.92329018587293), + new Coordinate(10.700285749621997, 59.92347619027632), + new Coordinate(10.704714696822037, 59.92272030268688), + new Coordinate(10.71001707489603, 59.92597766029715), + new Coordinate(10.707838597058043, 59.92676341291536), + new Coordinate(10.708389137506913, 59.92790300889098), + new Coordinate(10.707060536853078, 59.928376832499424), + new Coordinate(10.705803789539402, 59.92831087551576), + new Coordinate(10.706641515204467, 59.92953431964068), + new Coordinate(10.70484606360543, 59.93046383654274), + new Coordinate(10.701817874860211, 59.93008590667682), + new Coordinate(10.700525251174469, 59.93028982601595), + new Coordinate(10.69770054003061, 59.92939032560119), + }); } diff --git a/street/src/test-fixtures/java/org/opentripplanner/street/linking/LinkingEnvironment.java b/street/src/test-fixtures/java/org/opentripplanner/street/linking/LinkingEnvironment.java index a6f8f4a4960..48f742cc593 100644 --- a/street/src/test-fixtures/java/org/opentripplanner/street/linking/LinkingEnvironment.java +++ b/street/src/test-fixtures/java/org/opentripplanner/street/linking/LinkingEnvironment.java @@ -82,13 +82,13 @@ public void linkVertexPermanently(TransitStopVertex linkedVertex) { linkedVertex, new TraverseModeSet(TraverseMode.WALK), BIDIRECTIONAL, - ((vertex, streetVertex) -> { + (vertex, streetVertex) -> { var s = (TransitStopVertex) vertex; return List.of( StreetTransitStopLink.createStreetTransitStopLink(s, streetVertex), StreetTransitStopLink.createStreetTransitStopLink(streetVertex, s) ); - }) + } ); } diff --git a/street/src/test-fixtures/java/org/opentripplanner/street/model/edge/TestAreaGroupBuilder.java b/street/src/test-fixtures/java/org/opentripplanner/street/model/edge/TestAreaGroupBuilder.java index 15d79776313..8e8ba5729a0 100644 --- a/street/src/test-fixtures/java/org/opentripplanner/street/model/edge/TestAreaGroupBuilder.java +++ b/street/src/test-fixtures/java/org/opentripplanner/street/model/edge/TestAreaGroupBuilder.java @@ -62,9 +62,10 @@ private static void connectAreaEdge( AreaGroup areaGroup, boolean back ) { - var geometry = GeometryUtils.getGeometryFactory().createLineString( - new Coordinate[] { from.getCoordinate(), to.getCoordinate() } - ); + var geometry = GeometryUtils.getGeometryFactory().createLineString(new Coordinate[] { + from.getCoordinate(), + to.getCoordinate(), + }); new AreaEdgeBuilder() .withFromVertex(from) .withToVertex(to) diff --git a/street/src/test-fixtures/java/org/opentripplanner/street/model/elevation/ElevationProfiles.java b/street/src/test-fixtures/java/org/opentripplanner/street/model/elevation/ElevationProfiles.java index ac294740c88..77a67017ee3 100644 --- a/street/src/test-fixtures/java/org/opentripplanner/street/model/elevation/ElevationProfiles.java +++ b/street/src/test-fixtures/java/org/opentripplanner/street/model/elevation/ElevationProfiles.java @@ -7,16 +7,16 @@ public class ElevationProfiles { /// An elevation profile that exceeds the maximum uphill slope limit of 35%. public static final PackedCoordinateSequence.Double STEEP_ELEVATION_PROFILE = - new PackedCoordinateSequence.Double( - new Coordinate[] { - new Coordinate(0, 6972), - new Coordinate(25, 6985), - new Coordinate(50, 6967), - } - ); + new PackedCoordinateSequence.Double(new Coordinate[] { + new Coordinate(0, 6972), + new Coordinate(25, 6985), + new Coordinate(50, 6967), + }); public static final PackedCoordinateSequence.Double STEEP_DOWNHILL_PROFILE = - new PackedCoordinateSequence.Double( - new Coordinate[] { new Coordinate(0, 1000), new Coordinate(25, 800), new Coordinate(50, 700) } - ); + new PackedCoordinateSequence.Double(new Coordinate[] { + new Coordinate(0, 1000), + new Coordinate(25, 800), + new Coordinate(50, 700), + }); } diff --git a/street/src/test/java/org/opentripplanner/street/geometry/DirectionUtilsTest.java b/street/src/test/java/org/opentripplanner/street/geometry/DirectionUtilsTest.java index 10fc00f0a71..211fc5c08f5 100644 --- a/street/src/test/java/org/opentripplanner/street/geometry/DirectionUtilsTest.java +++ b/street/src/test/java/org/opentripplanner/street/geometry/DirectionUtilsTest.java @@ -81,7 +81,7 @@ public final void testAzimuth() { double maxError = 0.0; for (int i = 0; i < exactAzimuths.length; i++) { // Degrees - double error = (exactAzimuths[i] - approxAzimuths[i]); + double error = exactAzimuths[i] - approxAzimuths[i]; if (error > 360) { error -= 360; } diff --git a/street/src/test/java/org/opentripplanner/street/geometry/PolylineEncoderTest.java b/street/src/test/java/org/opentripplanner/street/geometry/PolylineEncoderTest.java index eabd56039fd..810ac851db8 100644 --- a/street/src/test/java/org/opentripplanner/street/geometry/PolylineEncoderTest.java +++ b/street/src/test/java/org/opentripplanner/street/geometry/PolylineEncoderTest.java @@ -23,14 +23,12 @@ public void testCreateEncodingsOfCoordinateArray() { @Test public void testPolygon() { - var polygon = GeometryUtils.getGeometryFactory().createPolygon( - new Coordinate[] { - new Coordinate(0, 0), - new Coordinate(1, 1), - new Coordinate(2, 2), - new Coordinate(0, 0), - } - ); + var polygon = GeometryUtils.getGeometryFactory().createPolygon(new Coordinate[] { + new Coordinate(0, 0), + new Coordinate(1, 1), + new Coordinate(2, 2), + new Coordinate(0, 0), + }); var polyline = PolylineEncoder.encodeGeometry(polygon); assertEquals("??_ibE_ibE_ibE_ibE~reK~reK", polyline.points()); diff --git a/street/src/test/java/org/opentripplanner/street/graph/GraphTest.java b/street/src/test/java/org/opentripplanner/street/graph/GraphTest.java index 2d4ecbe96ff..fb414dc3c2a 100644 --- a/street/src/test/java/org/opentripplanner/street/graph/GraphTest.java +++ b/street/src/test/java/org/opentripplanner/street/graph/GraphTest.java @@ -1,10 +1,10 @@ package org.opentripplanner.street.graph; +import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.opentripplanner.street.model.StreetModelFactory.intersectionVertex; -import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -53,7 +53,7 @@ void testAddEdge() { } @Test - void testGetEdgesOneEdge() { + void testListEdgesOneEdge() { Graph g = new Graph(); Vertex a = intersectionVertex("A", 5, 5); Vertex b = intersectionVertex("B", 6, 6); @@ -61,15 +61,12 @@ void testGetEdgesOneEdge() { g.addVertex(a); g.addVertex(b); - FreeEdge ee = FreeEdge.createFreeEdge(a, b); - - List edges = new ArrayList<>(g.getEdges()); - assertEquals(1, edges.size()); - assertEquals(ee, edges.get(0)); + var ee = FreeEdge.createFreeEdge(a, b); + assertThat(g.listEdges()).containsExactlyElementsIn(Set.of(ee)); } @Test - void testGetEdgesMultiple() { + void testListEdgesMultiple() { Graph g = new Graph(); Vertex a = intersectionVertex("A", 5, 5); Vertex b = intersectionVertex("B", 6, 6); @@ -85,9 +82,24 @@ void testGetEdgesMultiple() { expectedEdges.add(FreeEdge.createFreeEdge(c, b)); expectedEdges.add(FreeEdge.createFreeEdge(c, a)); - Set edges = new HashSet<>(g.getEdges()); - assertEquals(4, edges.size()); - assertEquals(expectedEdges, edges); + assertThat(g.listEdges()).containsExactlyElementsIn(expectedEdges); + } + + @Test + void testListEdgesCanBeIteratedMoreThanOnce() { + Graph g = new Graph(); + var a = intersectionVertex("A", 5, 5); + var b = intersectionVertex("B", 6, 6); + var e = FreeEdge.createFreeEdge(a, b); + + g.addVertex(a); + g.addVertex(b); + + Iterable edges = g.listEdges(); + + // Make sure the Iterable creates a new iterator every time it is called + assertThat(edges).containsExactlyElementsIn(List.of(e)); + assertThat(edges).containsExactlyElementsIn(List.of(e)); } @Test @@ -103,8 +115,7 @@ void testGetStreetEdgesNone() { allEdges.add(FreeEdge.createFreeEdge(c, b)); allEdges.add(FreeEdge.createFreeEdge(c, a)); - Set edges = new HashSet<>(g.getStreetEdges()); - assertEquals(0, edges.size()); + assertThat(g.findEdges(StreetEdge.class)).isEmpty(); } @Test @@ -124,9 +135,32 @@ void testGetStreetEdgesSeveral() { allStreetEdges.add(edge(c, b, 1.0)); allStreetEdges.add(edge(c, a, 1.0)); - Set edges = new HashSet<>(g.getStreetEdges()); - assertEquals(4, edges.size()); - assertEquals(allStreetEdges, edges); + assertThat(g.findEdges(StreetEdge.class)).containsExactlyElementsIn(allStreetEdges); + } + + @Test + void iterateEdgesFiltersByType() { + Graph g = new Graph(); + StreetVertex a = intersectionVertex("A", 5, 5); + StreetVertex b = intersectionVertex("B", 6, 6); + StreetVertex c = intersectionVertex("C", 3, 2); + + g.addVertex(a); + g.addVertex(b); + g.addVertex(c); + + StreetEdge streetEdge = edge(a, b, 1.0); + FreeEdge freeEdge = FreeEdge.createFreeEdge(b, c); + + assertThat(g.findEdges(StreetEdge.class)).containsExactly(streetEdge); + assertThat(g.findEdges(FreeEdge.class)).containsExactly(freeEdge); + assertThat(g.findEdges(Edge.class)).containsExactly(streetEdge, freeEdge); + } + + @Test + void iterateEdgesEmptyGraph() { + Graph g = new Graph(); + assertThat(g.findEdges(Edge.class)).isEmpty(); } /** diff --git a/street/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java b/street/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java index 57446ec7f9e..a979e5e5571 100644 --- a/street/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java +++ b/street/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java @@ -165,7 +165,8 @@ public void testFallBackToWalking() { @Test public void testNoBikesAvailable() { // Replace B1 with a station that has no bikes available - var stationWithNoBikes = ((VehicleRentalStation) B1.getStation()).copyOf() + var stationWithNoBikes = ((VehicleRentalStation) B1.getStation()) + .copyOf() .withVehiclesAvailable(0) .build(); B1.setStation(stationWithNoBikes); @@ -192,7 +193,8 @@ public void testNoBikesAvailable() { @Test public void testNoSpacesAvailable() { // Replace B2 with a station that has no spaces available - var stationWithNoSpaces = ((VehicleRentalStation) B2.getStation()).copyOf() + var stationWithNoSpaces = ((VehicleRentalStation) B2.getStation()) + .copyOf() .withSpacesAvailable(0) .withVehicleSpacesAvailable(Map.of()) .build(); @@ -220,7 +222,8 @@ public void testNoSpacesAvailable() { @Test public void testIgnoreAvailabilityNoBikesAvailable() { // Replace B1 with a station that has no bikes available - var stationWithNoBikes = ((VehicleRentalStation) B1.getStation()).copyOf() + var stationWithNoBikes = ((VehicleRentalStation) B1.getStation()) + .copyOf() .withVehiclesAvailable(0) .build(); B1.setStation(stationWithNoBikes); @@ -239,7 +242,8 @@ public void testIgnoreAvailabilityNoBikesAvailable() { @Test public void testIgnoreAvailabilityNoSpacesAvailable() { // Replace B2 with a station that has no spaces available - var stationWithNoSpaces = ((VehicleRentalStation) B2.getStation()).copyOf() + var stationWithNoSpaces = ((VehicleRentalStation) B2.getStation()) + .copyOf() .withSpacesAvailable(0) .build(); B2.setStation(stationWithNoSpaces); @@ -298,7 +302,8 @@ public void testFloatingBike() { @Test public void testBikeRentalFromStationWantToKeepCantKeep() { // Replace B1 with a station that doesn't allow keeping vehicles at destination - var stationCantKeep = ((VehicleRentalStation) B1.getStation()).copyOf() + var stationCantKeep = ((VehicleRentalStation) B1.getStation()) + .copyOf() .withIsArrivingInRentalVehicleAtDestinationAllowed(false) .build(); B1.setStation(stationCantKeep); @@ -337,7 +342,8 @@ public void testBikeRentalFromStationWantToKeepCantKeep() { @Test public void testBikeRentalFromStationWantToKeepCanKeep() { // Replace B1 with a station that allows keeping vehicles at destination - var stationCanKeep = ((VehicleRentalStation) B1.getStation()).copyOf() + var stationCanKeep = ((VehicleRentalStation) B1.getStation()) + .copyOf() .withIsArrivingInRentalVehicleAtDestinationAllowed(true) .build(); B1.setStation(stationCanKeep); @@ -376,7 +382,8 @@ public void testBikeRentalFromStationWantToKeepCanKeep() { @Test public void testBikeRentalFromStationWantToKeepCanKeepButCostly() { // Replace B1 with a station that allows keeping vehicles at destination - var stationCanKeep = ((VehicleRentalStation) B1.getStation()).copyOf() + var stationCanKeep = ((VehicleRentalStation) B1.getStation()) + .copyOf() .withIsArrivingInRentalVehicleAtDestinationAllowed(true) .build(); B1.setStation(stationCanKeep); diff --git a/street/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java b/street/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java index d7ecaffb850..5991b3d62e4 100644 --- a/street/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java +++ b/street/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java @@ -409,7 +409,7 @@ private List runStreetSearchAndCreateDescriptor( s.getBackMode() != null && s.isBackWalkingBike() ? "🚲" : "", s.getBackMode(), s.getTimeDeltaSeconds(), - s.getBackEdge() != null ? ((double) Math.round(s.getWeightDelta() * 10)) / 10 : 0.0, + s.getBackEdge() != null ? (double) Math.round(s.getWeightDelta() * 10) / 10 : 0.0, s.getBackEdge() != null ? s.getBackEdge().getDefaultName() : null ) ) diff --git a/street/src/test/java/org/opentripplanner/street/linking/PlatformLinkingTest.java b/street/src/test/java/org/opentripplanner/street/linking/PlatformLinkingTest.java index 2da926e097d..21b79acc961 100644 --- a/street/src/test/java/org/opentripplanner/street/linking/PlatformLinkingTest.java +++ b/street/src/test/java/org/opentripplanner/street/linking/PlatformLinkingTest.java @@ -525,9 +525,10 @@ private AreaEdgeBuilder createAreaEdge( AreaGroup area, String nameString ) { - LineString line = GEOMETRY_FACTORY.createLineString( - new Coordinate[] { v1.getCoordinate(), v2.getCoordinate() } - ); + LineString line = GEOMETRY_FACTORY.createLineString(new Coordinate[] { + v1.getCoordinate(), + v2.getCoordinate(), + }); I18NString name = new LocalizedString(nameString); return new AreaEdgeBuilder() .withFromVertex(v1) diff --git a/street/src/test/java/org/opentripplanner/street/linking/PreparedAreaGroupTest.java b/street/src/test/java/org/opentripplanner/street/linking/PreparedAreaGroupTest.java index 6049d46b705..f0e3d1c19a6 100644 --- a/street/src/test/java/org/opentripplanner/street/linking/PreparedAreaGroupTest.java +++ b/street/src/test/java/org/opentripplanner/street/linking/PreparedAreaGroupTest.java @@ -141,36 +141,30 @@ private static Area area(Polygon geometry) { } private static Polygon square(double minX, double maxX) { - return GF.createPolygon( - new Coordinate[] { - new Coordinate(minX, 0), - new Coordinate(maxX, 0), - new Coordinate(maxX, 10), - new Coordinate(minX, 10), - new Coordinate(minX, 0), - } - ); + return GF.createPolygon(new Coordinate[] { + new Coordinate(minX, 0), + new Coordinate(maxX, 0), + new Coordinate(maxX, 10), + new Coordinate(minX, 10), + new Coordinate(minX, 0), + }); } private static Polygon squareWithHole() { - LinearRing shell = GF.createLinearRing( - new Coordinate[] { - new Coordinate(0, 0), - new Coordinate(10, 0), - new Coordinate(10, 10), - new Coordinate(0, 10), - new Coordinate(0, 0), - } - ); - LinearRing hole = GF.createLinearRing( - new Coordinate[] { - new Coordinate(4, 4), - new Coordinate(6, 4), - new Coordinate(6, 6), - new Coordinate(4, 6), - new Coordinate(4, 4), - } - ); + LinearRing shell = GF.createLinearRing(new Coordinate[] { + new Coordinate(0, 0), + new Coordinate(10, 0), + new Coordinate(10, 10), + new Coordinate(0, 10), + new Coordinate(0, 0), + }); + LinearRing hole = GF.createLinearRing(new Coordinate[] { + new Coordinate(4, 4), + new Coordinate(6, 4), + new Coordinate(6, 6), + new Coordinate(4, 6), + new Coordinate(4, 4), + }); return GF.createPolygon(shell, new LinearRing[] { hole }); } } diff --git a/street/src/test/java/org/opentripplanner/street/linking/VehicleParkingHelperTest.java b/street/src/test/java/org/opentripplanner/street/linking/VehicleParkingHelperTest.java index 9702b9c469f..ce545d486c7 100644 --- a/street/src/test/java/org/opentripplanner/street/linking/VehicleParkingHelperTest.java +++ b/street/src/test/java/org/opentripplanner/street/linking/VehicleParkingHelperTest.java @@ -1,5 +1,6 @@ package org.opentripplanner.street.linking; +import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -47,14 +48,13 @@ void linkSkippingEdgesTest() { .entrances( IntStream.rangeClosed(1, 3) .mapToObj( - id -> - builder -> - builder - .entranceId(new FeedScopedId(TEST_FEED_ID, "Entrance " + id)) - .name(new NonLocalizedString("Entrance " + id)) - .coordinate(new WgsCoordinate(id, id)) - .carAccessible(id == 1 || id == 3) - .walkAccessible(id == 2 || id == 3) + id -> builder -> + builder + .entranceId(new FeedScopedId(TEST_FEED_ID, "Entrance " + id)) + .name(new NonLocalizedString("Entrance " + id)) + .coordinate(new WgsCoordinate(id, id)) + .carAccessible(id == 1 || id == 3) + .walkAccessible(id == 2 || id == 3) ) .collect(Collectors.toList()) ) @@ -64,7 +64,7 @@ void linkSkippingEdgesTest() { new VehicleParkingHelper(graph).linkVehicleParkingToGraph(vehicleParking); assertEquals(3, graph.getVerticesOfType(VehicleParkingEntranceVertex.class).size()); - assertEquals(7, graph.getEdgesOfType(VehicleParkingEdge.class).size()); + assertThat(graph.findEdges(VehicleParkingEdge.class)).hasSize(7); } private VehicleParking createParingWithEntrances(int entranceNumber) { @@ -73,13 +73,12 @@ private VehicleParking createParingWithEntrances(int entranceNumber) { .entrances( IntStream.rangeClosed(1, entranceNumber) .mapToObj( - id -> - builder -> - builder - .entranceId(new FeedScopedId(TEST_FEED_ID, "Entrance " + id)) - .name(new NonLocalizedString("Entrance " + id)) - .coordinate(new WgsCoordinate(id, id)) - .walkAccessible(true) + id -> builder -> + builder + .entranceId(new FeedScopedId(TEST_FEED_ID, "Entrance " + id)) + .name(new NonLocalizedString("Entrance " + id)) + .coordinate(new WgsCoordinate(id, id)) + .walkAccessible(true) ) .collect(Collectors.toList()) ) diff --git a/street/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeSplittingTest.java b/street/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeSplittingTest.java index b4afd93b228..878d7459199 100644 --- a/street/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeSplittingTest.java +++ b/street/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeSplittingTest.java @@ -31,9 +31,10 @@ public void testSplitting() { for (double delta = 0; delta <= 2; delta += 0.005) { StreetVertex v0 = intersectionVertex("zero", x, y); StreetVertex v1 = intersectionVertex("one", x + delta, y + delta); - LineString geom = gf.createLineString( - new Coordinate[] { v0.getCoordinate(), v1.getCoordinate() } - ); + LineString geom = gf.createLineString(new Coordinate[] { + v0.getCoordinate(), + v1.getCoordinate(), + }); double dist = SphericalDistanceLibrary.distance(v0.getCoordinate(), v1.getCoordinate()); StreetEdge s0 = new StreetEdgeBuilder<>() .withFromVertex(v0) @@ -73,10 +74,14 @@ public void testSplitting() { var sp0 = s0.splitDestructively(sv0); var sp1 = s1.splitDestructively(sv1); - // distances expressed internally in mm so this epsilon is plenty good enough to ensure that they - // have the same values - assertEquals(sp0.head().getDistanceMeters(), sp1.tail().getDistanceMeters(), 0.0000001); - assertEquals(sp0.tail().getDistanceMeters(), sp1.head().getDistanceMeters(), 0.0000001); + // distances are expressed internally as whole millimeters, but the split fraction for the + // forward and back edges is computed independently from their (forward vs. reversed) + // geometries. SphericalDistanceLibrary.distance(a, b) is not perfectly bit-symmetric under + // swapping a and b, so the two independent millimeter roundings can occasionally differ by + // 1 mm (0.001 m). Use an epsilon slightly larger than that to avoid flakiness while still + // catching real regressions. + assertEquals(sp0.head().getDistanceMeters(), sp1.tail().getDistanceMeters(), 0.0011); + assertEquals(sp0.tail().getDistanceMeters(), sp1.head().getDistanceMeters(), 0.0011); assertFalse(sp0.head().isBack()); assertFalse(sp0.tail().isBack()); assertTrue(sp1.head().isBack()); diff --git a/street/src/test/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeTest.java b/street/src/test/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeTest.java index f5bfae9879f..80cf41bf7f5 100644 --- a/street/src/test/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeTest.java +++ b/street/src/test/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeTest.java @@ -58,7 +58,6 @@ public void testConstruction() { e1.getDistanceMeters() ); - assertTrue(pEdge.isEquivalentTo(e1)); assertFalse(pEdge.isBack()); assertFalse(pEdge.isReverseOf(e1)); assertTrue(pEdge.isReverseOf(e1Reverse)); diff --git a/street/src/test/java/org/opentripplanner/street/model/elevation/ElevationProfileSlicerTest.java b/street/src/test/java/org/opentripplanner/street/model/elevation/ElevationProfileSlicerTest.java index a4a7abbbb71..3d6dc809a20 100644 --- a/street/src/test/java/org/opentripplanner/street/model/elevation/ElevationProfileSlicerTest.java +++ b/street/src/test/java/org/opentripplanner/street/model/elevation/ElevationProfileSlicerTest.java @@ -39,18 +39,26 @@ void slice() { assertPartialElevation(four_point, 5, 25, new double[] { 0, 105, 5, 110, 15, 120, 20, 125 }); assertPartialElevation(small_run, 10, 20.5, new double[] { 0, 110, 10, 120, 10.5, 120.5 }); - assertPartialElevation( - small_run, + assertPartialElevation(small_run, 0, 20.25, new double[] { 0, + 100, + 10, + 110, + 20, + 120, 20.25, - new double[] { 0, 100, 10, 110, 20, 120, 20.25, 120.25 } - ); - assertPartialElevation( - small_run, - 0.25, - 20.25, - new double[] { 0, 100.25, 9.75, 110, 19.75, 120, 20, 120.25 } - ); + 120.25, + }); + assertPartialElevation(small_run, 0.25, 20.25, new double[] { + 0, + 100.25, + 9.75, + 110, + 19.75, + 120, + 20, + 120.25, + }); } private static void assertPartialElevation( @@ -71,9 +79,8 @@ private static void assertPartialElevation( 2, 0 ).toCoordinateArray(); - var actualElevationProfile = partialElevationProfile != null - ? partialElevationProfile.toCoordinateArray() - : null; + var actualElevationProfile = + partialElevationProfile != null ? partialElevationProfile.toCoordinateArray() : null; assertArrayEquals(expectedElevationProfile, actualElevationProfile); } } diff --git a/street/src/test/java/org/opentripplanner/street/model/elevation/SlopeCostCalculatorTest.java b/street/src/test/java/org/opentripplanner/street/model/elevation/SlopeCostCalculatorTest.java index c19d8128a05..8e6963a83dd 100644 --- a/street/src/test/java/org/opentripplanner/street/model/elevation/SlopeCostCalculatorTest.java +++ b/street/src/test/java/org/opentripplanner/street/model/elevation/SlopeCostCalculatorTest.java @@ -19,9 +19,10 @@ class SlopeCostCalculatorTest { @Test void testLengthMultiplier() { PackedCoordinateSequenceFactory factory = PackedCoordinateSequenceFactory.DOUBLE_FACTORY; - CoordinateSequence seq = factory.create( - new Coordinate[] { new Coordinate(0, 1), new Coordinate(10, 1) } - ); + CoordinateSequence seq = factory.create(new Coordinate[] { + new Coordinate(0, 1), + new Coordinate(10, 1), + }); SlopeCosts costs = SlopeCostCalculator.getSlopeCosts(seq); assertEquals(1.0, costs.lengthMultiplier); @@ -29,9 +30,11 @@ void testLengthMultiplier() { costs = SlopeCostCalculator.getSlopeCosts(seq); assertEquals(1.00498756211208902702, costs.lengthMultiplier); - seq = factory.create( - new Coordinate[] { new Coordinate(0, 1), new Coordinate(10, 2), new Coordinate(15, 1) } - ); + seq = factory.create(new Coordinate[] { + new Coordinate(0, 1), + new Coordinate(10, 2), + new Coordinate(15, 1), + }); costs = SlopeCostCalculator.getSlopeCosts(seq); assertEquals(1.00992634231424500668, costs.lengthMultiplier); } @@ -121,8 +124,9 @@ void flattenedFlagSetOnlyAbove100Percent() { } private static PackedCoordinateSequence flatProfile() { - return new PackedCoordinateSequence.Double( - new Coordinate[] { new Coordinate(0, 100), new Coordinate(50, 100) } - ); + return new PackedCoordinateSequence.Double(new Coordinate[] { + new Coordinate(0, 100), + new Coordinate(50, 100), + }); } } diff --git a/street/src/test/java/org/opentripplanner/street/search/intersection_model/SimpleIntersectionTraversalCalculatorTest.java b/street/src/test/java/org/opentripplanner/street/search/intersection_model/SimpleIntersectionTraversalCalculatorTest.java index 185c3cdfb81..b415db9926a 100644 --- a/street/src/test/java/org/opentripplanner/street/search/intersection_model/SimpleIntersectionTraversalCalculatorTest.java +++ b/street/src/test/java/org/opentripplanner/street/search/intersection_model/SimpleIntersectionTraversalCalculatorTest.java @@ -66,7 +66,7 @@ public void testCalculateTurnAngle() { assertEquals(-180, e3.getOutAngle()); // Difference should be about 90. - int diff = (e1.getOutAngle() - e3.getInAngle()); + int diff = e1.getOutAngle() - e3.getInAngle(); assertEquals(90, diff); int turnAngle = calculateTurnAngle(e1, e3); diff --git a/utils/pom.xml b/utils/pom.xml index f623d82a6ee..10d11bb6139 100644 --- a/utils/pom.xml +++ b/utils/pom.xml @@ -15,8 +15,8 @@ - com.hubspot.maven.plugins - prettier-maven-plugin + com.diffplug.spotless + spotless-maven-plugin diff --git a/utils/src/main/java/org/opentripplanner/utils/collection/CollectionsView.java b/utils/src/main/java/org/opentripplanner/utils/collection/CollectionsView.java index 599846f9d86..e53a194ddb9 100644 --- a/utils/src/main/java/org/opentripplanner/utils/collection/CollectionsView.java +++ b/utils/src/main/java/org/opentripplanner/utils/collection/CollectionsView.java @@ -24,7 +24,8 @@ */ public class CollectionsView extends AbstractCollection - implements Collection, Serializable { + implements Collection, Serializable +{ private final Collection[] collections; diff --git a/utils/src/main/java/org/opentripplanner/utils/collection/ListUtils.java b/utils/src/main/java/org/opentripplanner/utils/collection/ListUtils.java index f274b23941b..737689d06ca 100644 --- a/utils/src/main/java/org/opentripplanner/utils/collection/ListUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/collection/ListUtils.java @@ -27,6 +27,28 @@ public static T last(List list) { return list == null || list.isEmpty() ? null : list.getLast(); } + /** + * Put all elements in the iterable into a list. + *

+ * Note: This is inefficient - do not use it in hot code paths and try to iterate instead. + */ + public static List ofIterable(Iterable iterable) { + var ret = new ArrayList(); + iterable.forEach(ret::add); + return ret; + } + + /** + * Count the number of elements in the iterable. + */ + public static int countIterable(Iterable iterable) { + int count = 0; + for (var _ : iterable) { + count++; + } + return count; + } + /** * Combine a number of collections into a single list. */ @@ -103,7 +125,7 @@ public static List ofNullable(@Nullable T input) { * called. */ public static List nullSafeImmutableList(@Nullable Collection c) { - return (c == null) ? List.of() : List.copyOf(c); + return c == null ? List.of() : List.copyOf(c); } /** diff --git a/utils/src/main/java/org/opentripplanner/utils/collection/StreamUtils.java b/utils/src/main/java/org/opentripplanner/utils/collection/StreamUtils.java index e6fc57fc6c9..2f20e35037e 100644 --- a/utils/src/main/java/org/opentripplanner/utils/collection/StreamUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/collection/StreamUtils.java @@ -2,6 +2,7 @@ import java.util.Collection; import java.util.stream.Stream; +import java.util.stream.StreamSupport; import javax.annotation.Nullable; public class StreamUtils { @@ -16,4 +17,11 @@ public static Stream ofNullableCollection(@Nullable Collection value) return value.stream(); } } + + /** + * Converts the given {@code Iterable} into a sequential {@code Stream}. + */ + public static Stream ofIterable(Iterable iterable) { + return StreamSupport.stream(iterable.spliterator(), false); + } } diff --git a/utils/src/main/java/org/opentripplanner/utils/lang/BitSetUtils.java b/utils/src/main/java/org/opentripplanner/utils/lang/BitSetUtils.java index afb9654e56e..0ff8eb539a4 100644 --- a/utils/src/main/java/org/opentripplanner/utils/lang/BitSetUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/lang/BitSetUtils.java @@ -31,7 +31,7 @@ public static boolean get(byte bitset, int index) { public static byte set(byte bitset, int index, boolean value) { if (value) { - bitset |= (1 << index); + bitset |= 1 << index; } else { bitset &= ~(1 << index); } @@ -44,7 +44,7 @@ public static boolean get(short bitset, int index) { public static short set(short bitset, int index, boolean value) { if (value) { - bitset |= (1 << index); + bitset |= 1 << index; } else { bitset &= ~(1 << index); } @@ -57,7 +57,7 @@ public static boolean get(int bitset, int index) { public static int set(int bitset, int index, boolean value) { if (value) { - bitset |= (1 << index); + bitset |= 1 << index; } else { bitset &= ~(1 << index); } @@ -70,7 +70,7 @@ public static boolean get(long bitset, int index) { public static long set(long bitset, int index, boolean value) { if (value) { - bitset |= (1L << index); + bitset |= 1L << index; } else { bitset &= ~(1L << index); } diff --git a/utils/src/main/java/org/opentripplanner/utils/lang/ObjectUtils.java b/utils/src/main/java/org/opentripplanner/utils/lang/ObjectUtils.java index f1c0c5d77fb..53986d8e42c 100644 --- a/utils/src/main/java/org/opentripplanner/utils/lang/ObjectUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/lang/ObjectUtils.java @@ -59,7 +59,7 @@ public static T requireNotInitialized( if (oldValue != null) { throw new IllegalStateException( "Field%s is already set! Old value: %s, new value: %s.".formatted( - (name == null ? "" : " " + name), + name == null ? "" : " " + name, oldValue, newValue ) diff --git a/utils/src/main/java/org/opentripplanner/utils/time/DateUtils.java b/utils/src/main/java/org/opentripplanner/utils/time/DateUtils.java index 643c7174051..99464b6d515 100644 --- a/utils/src/main/java/org/opentripplanner/utils/time/DateUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/time/DateUtils.java @@ -98,7 +98,7 @@ public static LocalDate parseDate(String input) { newString.substring(4, 6) + '.' + newString.substring(6, 8); - } else if (!(newString.matches(".*20\\d\\d.*"))) { + } else if (!newString.matches(".*20\\d\\d.*")) { // if it looks like we have a small date format, ala 11.4.09, then use // another set of compares dateTimeFormatterList = SMALL_DF_LIST; diff --git a/utils/src/main/java/org/opentripplanner/utils/time/ServiceDateUtils.java b/utils/src/main/java/org/opentripplanner/utils/time/ServiceDateUtils.java index 9af07836e9a..9b025e50b00 100644 --- a/utils/src/main/java/org/opentripplanner/utils/time/ServiceDateUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/time/ServiceDateUtils.java @@ -157,7 +157,7 @@ public static List calculateRunningDates( * is negative. */ public static int wholeDays(int seconds) { - return seconds < 0 ? 0 : (seconds / SECONDS_IN_A_DAY); + return seconds < 0 ? 0 : seconds / SECONDS_IN_A_DAY; } /** diff --git a/utils/src/main/java/org/opentripplanner/utils/time/TimeUtils.java b/utils/src/main/java/org/opentripplanner/utils/time/TimeUtils.java index 459be48a5ac..299566cf3ce 100644 --- a/utils/src/main/java/org/opentripplanner/utils/time/TimeUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/time/TimeUtils.java @@ -31,7 +31,7 @@ public class TimeUtils { private TimeUtils() {} public static int hms2time(int hour, int minute, int second) { - return second + 60 * (minute + (60 * hour)); + return second + 60 * (minute + 60 * hour); } public static int hm2time(int hour, int minute) { @@ -257,7 +257,7 @@ public static long busyWait(int waitMs) { long value = rnd.nextLong(); // Print wait, this method is for debugging only - System.err.printf(Locale.ROOT, "BUSY-WAIT (%.1fs)%n", (waitMs / 1000.0)); + System.err.printf(Locale.ROOT, "BUSY-WAIT (%.1fs)%n", waitMs / 1000.0); while (System.currentTimeMillis() < waitUntil) { value |= rnd.nextLong(); diff --git a/utils/src/main/java/org/opentripplanner/utils/tostring/ToStringBuilder.java b/utils/src/main/java/org/opentripplanner/utils/tostring/ToStringBuilder.java index af3cbd8b0cb..c2fcd0f8cc2 100644 --- a/utils/src/main/java/org/opentripplanner/utils/tostring/ToStringBuilder.java +++ b/utils/src/main/java/org/opentripplanner/utils/tostring/ToStringBuilder.java @@ -248,8 +248,8 @@ public ToStringBuilder addIntArraySize(String name, int[] array, int notSet) { return addIt( name, Arrays.stream(array) - .filter(t -> t != notSet) - .count() + + .filter(t -> t != notSet) + .count() + "/" + array.length ); diff --git a/utils/src/test/java/org/opentripplanner/utils/collection/ListUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/collection/ListUtilsTest.java index d995b1af36b..740fe400dca 100644 --- a/utils/src/test/java/org/opentripplanner/utils/collection/ListUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/collection/ListUtilsTest.java @@ -1,5 +1,6 @@ package org.opentripplanner.utils.collection; +import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -8,6 +9,7 @@ import static org.opentripplanner.utils.collection.ListUtils.requireAtLeastNElements; import java.util.List; +import java.util.Set; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -74,6 +76,24 @@ void distinctByKey() { assertEquals(List.of(first, third), deduplicated); } + @Test + void ofIterableEmpty() { + assertThat(ListUtils.ofIterable(List.of())).isEmpty(); + } + + @Test + void ofIterableList() { + assertThat(ListUtils.ofIterable(List.of(1, 2, 3))) + .containsExactly(1, 2, 3) + .inOrder(); + } + + @Test + void ofIterableNonCollectionIterable() { + Iterable iterable = Set.of(1, 2, 3)::iterator; + assertThat(ListUtils.ofIterable(iterable)).containsExactly(1, 2, 3); + } + @Test void ofNullable() { assertEquals(List.of(), ListUtils.ofNullable(null)); diff --git a/utils/src/test/java/org/opentripplanner/utils/collection/StreamUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/collection/StreamUtilsTest.java index f6e0f3c0f24..b6028fcac70 100644 --- a/utils/src/test/java/org/opentripplanner/utils/collection/StreamUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/collection/StreamUtilsTest.java @@ -1,8 +1,10 @@ package org.opentripplanner.utils.collection; +import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.List; +import java.util.Set; import org.junit.jupiter.api.Test; class StreamUtilsTest { @@ -26,4 +28,22 @@ void nullableCollectionOneElement() { void nullableCollectionTwoElements() { assertEquals(List.of(1, 2), StreamUtils.ofNullableCollection(List.of(1, 2)).toList()); } + + @Test + void ofIterableEmpty() { + assertThat(StreamUtils.ofIterable(List.of()).toList()).isEmpty(); + } + + @Test + void ofIterableList() { + assertThat(StreamUtils.ofIterable(List.of(1, 2, 3)).toList()) + .containsExactly(1, 2, 3) + .inOrder(); + } + + @Test + void ofIterableNonCollectionIterable() { + Iterable iterable = Set.of(1, 2, 3)::iterator; + assertThat(StreamUtils.ofIterable(iterable).toList()).containsExactly(1, 2, 3); + } } diff --git a/utils/src/test/java/org/opentripplanner/utils/logging/ThrottleTest.java b/utils/src/test/java/org/opentripplanner/utils/logging/ThrottleTest.java index 3f021ab64f8..ad9601d99a0 100644 --- a/utils/src/test/java/org/opentripplanner/utils/logging/ThrottleTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/logging/ThrottleTest.java @@ -47,7 +47,7 @@ void manualTest() { .parallelStream() .forEach(i -> subject.throttle(() -> - System.err.printf(Locale.ROOT, "%d ms%n", (System.currentTimeMillis() - start)) + System.err.printf(Locale.ROOT, "%d ms%n", System.currentTimeMillis() - start) ) ); /* diff --git a/utils/src/test/java/org/opentripplanner/utils/text/HexStringTest.java b/utils/src/test/java/org/opentripplanner/utils/text/HexStringTest.java index 7efc4e3fa61..7c5cfef2432 100644 --- a/utils/src/test/java/org/opentripplanner/utils/text/HexStringTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/text/HexStringTest.java @@ -25,18 +25,16 @@ void testSingleElement() { void testLongString() { assertEquals( "0123456789abcdef", - HexString.of( - new byte[] { - (byte) 0x01, - (byte) 0x23, - (byte) 0x45, - (byte) 0x67, - (byte) 0x89, - (byte) 0xab, - (byte) 0xcd, - (byte) 0xef, - } - ) + HexString.of(new byte[] { + (byte) 0x01, + (byte) 0x23, + (byte) 0x45, + (byte) 0x67, + (byte) 0x89, + (byte) 0xab, + (byte) 0xcd, + (byte) 0xef, + }) ); } } diff --git a/utils/src/test/java/org/opentripplanner/utils/text/TableTest.java b/utils/src/test/java/org/opentripplanner/utils/text/TableTest.java index 958020b631e..6893eaab00c 100644 --- a/utils/src/test/java/org/opentripplanner/utils/text/TableTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/text/TableTest.java @@ -21,11 +21,11 @@ public void buildAndPrintTable() { .addRow(null, "Short", 123); var expected = """ - LEFT | CENTER | RIGHT - SPACE | Long-value | 2 - NL Before | NL in middle | NL after - | Short | 123 - """; + LEFT | CENTER | RIGHT + SPACE | Long-value | 2 + NL Before | NL in middle | NL after + | Short | 123 + """; // Both the builder and the Table returns the same table as toString() assertEquals(expected, builder.toString()); diff --git a/utils/src/test/java/org/opentripplanner/utils/time/DurationUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/time/DurationUtilsTest.java index 5973995d24f..cdc1206bc51 100644 --- a/utils/src/test/java/org/opentripplanner/utils/time/DurationUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/time/DurationUtilsTest.java @@ -49,7 +49,7 @@ public void durationToStrFromSeconds() { assertEquals("-13h33m57s", DurationUtils.durationToStr(timeSeconds2)); int timeSeconds1 = -I9h31m; assertEquals("-9h31m", DurationUtils.durationToStr(timeSeconds1)); - int timeSeconds = -(int) D9s.toSeconds(); + int timeSeconds = -((int) D9s.toSeconds()); assertEquals("-9s", DurationUtils.durationToStr(timeSeconds)); int notSet = 999_999; diff --git a/utils/src/test/java/org/opentripplanner/utils/tostring/ToStringBuilderTest.java b/utils/src/test/java/org/opentripplanner/utils/tostring/ToStringBuilderTest.java index 0a900f5d194..bcf2e3f6ef4 100644 --- a/utils/src/test/java/org/opentripplanner/utils/tostring/ToStringBuilderTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/tostring/ToStringBuilderTest.java @@ -160,7 +160,9 @@ public void addObjOp() { public void addIntArray() { assertEquals( "ToStringBuilderTest{a: [1, 2, 3]}", - subject().addInts("a", new int[] { 1, 2, 3 }).toString() + subject() + .addInts("a", new int[] { 1, 2, 3 }) + .toString() ); } @@ -169,11 +171,15 @@ public void addDoubleArray() { assertEquals("ToStringBuilderTest{a: null}", subject().addDoubles("a", null, 1.0).toString()); assertEquals( "ToStringBuilderTest{b: [1.0, 3.0]}", - subject().addDoubles("b", new double[] { 1.0, 3.0 }, 1.0).toString() + subject() + .addDoubles("b", new double[] { 1.0, 3.0 }, 1.0) + .toString() ); assertEquals( "ToStringBuilderTest{}", - subject().addDoubles("c", new double[] { 1.0, 1.0 }, 1.0).toString() + subject() + .addDoubles("c", new double[] { 1.0, 1.0 }, 1.0) + .toString() ); } @@ -183,7 +189,9 @@ public void addCollection() { assertEquals("ToStringBuilderTest{}", subject().addCol("c", List.of()).toString()); assertEquals( "ToStringBuilderTest{c: [1, 3.0, true]}", - subject().addCol("c", List.of(1, 3d, true)).toString() + subject() + .addCol("c", List.of(1, 3d, true)) + .toString() ); } @@ -218,11 +226,15 @@ public void addCollectionWithCustomToStringOperation() { public void addCollectionWithLimit() { assertEquals( "ToStringBuilderTest{c: [1, 2, 3]}", - subject().addCollection("c", List.of(1, 2, 3), 2).toString() + subject() + .addCollection("c", List.of(1, 2, 3), 2) + .toString() ); assertEquals( "ToStringBuilderTest{c(2/4): [1, 2, ..]}", - subject().addCollection("c", List.of(1, 2, 3, 4), 2).toString() + subject() + .addCollection("c", List.of(1, 2, 3, 4), 2) + .toString() ); // null element in list @@ -240,7 +252,9 @@ public void addCollectionWithLimit() { public void addColSize() { assertEquals( "ToStringBuilderTest{c: 3 items}", - subject().addColSize("c", List.of(1, 3, 7)).toString() + subject() + .addColSize("c", List.of(1, 3, 7)) + .toString() ); assertEquals("ToStringBuilderTest{}", subject().addColSize("c", null).toString()); } @@ -249,7 +263,9 @@ public void addColSize() { public void addIntArraySize() { assertEquals( "ToStringBuilderTest{c: 2/3}", - subject().addIntArraySize("c", new int[] { 1, -1, 3 }, -1).toString() + subject() + .addIntArraySize("c", new int[] { 1, -1, 3 }, -1) + .toString() ); assertEquals("ToStringBuilderTest{}", subject().addIntArraySize("c", null, -1).toString()); } @@ -342,7 +358,9 @@ public void addDuration() { assertEquals("ToStringBuilderTest{d: 35s}", subject().addDurationSec("d", 35).toString()); assertEquals( "ToStringBuilderTest{d: 1d2h50m45s}", - subject().addDurationSec("d", (int) D1d2h50m45s.toSeconds()).toString() + subject() + .addDurationSec("d", (int) D1d2h50m45s.toSeconds()) + .toString() ); assertEquals("ToStringBuilderTest{d: 2m5s}", subject().addDuration("d", D2m5s).toString()); assertEquals("ToStringBuilderTest{}", subject().addDurationSec("d", 12, 12).toString()); diff --git a/utils/src/test/java/org/opentripplanner/utils/tostring/ValueObjectToStringBuilderTest.java b/utils/src/test/java/org/opentripplanner/utils/tostring/ValueObjectToStringBuilderTest.java index 01a9beac141..62175cc3d2e 100644 --- a/utils/src/test/java/org/opentripplanner/utils/tostring/ValueObjectToStringBuilderTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/tostring/ValueObjectToStringBuilderTest.java @@ -94,14 +94,24 @@ public void addCoordinate() { @Test public void addSecondsPastMidnight() { assertEquals("0:00:35", subject().addServiceTime(35).toString()); - assertEquals("2:50:45+1d", subject().addServiceTime((26 * 60 + 50) * 60 + 45).toString()); + assertEquals( + "2:50:45+1d", + subject() + .addServiceTime((26 * 60 + 50) * 60 + 45) + .toString() + ); assertEquals("23:59:59-1d", subject().addServiceTime(-1).toString()); } @Test public void addDuration() { assertEquals("35s", subject().addDurationSec(35).toString()); - assertEquals("1d2h50m45s", subject().addDurationSec((26 * 60 + 50) * 60 + 45).toString()); + assertEquals( + "1d2h50m45s", + subject() + .addDurationSec((26 * 60 + 50) * 60 + 45) + .toString() + ); assertEquals("35s", subject().addDuration(Duration.ofSeconds(35)).toString()); assertEquals("", subject().skipNull().addDurationSec(null).toString());