Skip to content

Commit 99fbbc1

Browse files
committed
Encapsulate EstimatedVehicleJourneyCodeAdapter in EstimatedVehicleJourneyWrapper
Move ownership of EstimatedVehicleJourneyCodeAdapter into EstimatedVehicleJourneyWrapper, which now exposes normalized serviceJourneyId() and datedServiceJourneyId() accessors instead of the raw estimatedVehicleJourneyCode(). EntityResolver and AddedTripBuilder obtain the normalized ids through the wrapper and no longer construct the adapter; the raw JAXB code is never handed out. resolveDatedServiceJourneyId now uses the DatedServiceJourney-normalized id so the read path matches the id under which AddedTripBuilder registers the added TripOnServiceDate (folds in #7774).
1 parent e2303a8 commit 99fbbc1

5 files changed

Lines changed: 130 additions & 17 deletions

File tree

application/src/main/java/org/opentripplanner/updater/trip/siri/AddedTripBuilder.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,12 @@ class AddedTripBuilder {
7474
this.deduplicator = deduplicator;
7575
// Verifying values required in SIRI Profile
7676
// Added ServiceJourneyId
77-
String estimatedVehicleJourneyCode = journey.estimatedVehicleJourneyCode();
78-
Objects.requireNonNull(estimatedVehicleJourneyCode, "EstimatedVehicleJourneyCode is required");
79-
var codeAdapter = new EstimatedVehicleJourneyCodeAdapter(estimatedVehicleJourneyCode);
80-
tripId = entityResolver.resolveId(codeAdapter.getServiceJourneyId());
81-
tripOnServiceDateId = entityResolver.resolveId(codeAdapter.getDatedServiceJourneyId());
77+
String serviceJourneyId = Objects.requireNonNull(
78+
journey.serviceJourneyId(),
79+
"EstimatedVehicleJourneyCode is required"
80+
);
81+
tripId = entityResolver.resolveId(serviceJourneyId);
82+
tripOnServiceDateId = entityResolver.resolveId(journey.datedServiceJourneyId());
8283

8384
// OperatorRef of added trip
8485
String operatorRef = Objects.requireNonNull(journey.operatorRef(), "OperatorRef is required");

application/src/main/java/org/opentripplanner/updater/trip/siri/EntityResolver.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,8 @@ public Trip resolveTrip(EstimatedVehicleJourneyWrapper journey) {
6565
}
6666

6767
// It is possible that the trip has previously been added, resolve the added trip
68-
if (journey.estimatedVehicleJourneyCode() != null) {
69-
var adapter = new EstimatedVehicleJourneyCodeAdapter(journey.estimatedVehicleJourneyCode());
70-
var addedTrip = transitService.getTrip(resolveId(adapter.getServiceJourneyId()));
68+
if (journey.serviceJourneyId() != null) {
69+
var addedTrip = transitService.getTrip(resolveId(journey.serviceJourneyId()));
7170
if (addedTrip != null) {
7271
return addedTrip;
7372
}
@@ -130,8 +129,10 @@ public FeedScopedId resolveDatedServiceJourneyId(EstimatedVehicleJourneyWrapper
130129
return resolveId(journey.datedVehicleJourneyRef());
131130
}
132131

133-
if (journey.estimatedVehicleJourneyCode() != null) {
134-
return resolveId(journey.estimatedVehicleJourneyCode());
132+
// The added TripOnServiceDate is registered under the DatedServiceJourney-normalized id, so the
133+
// code must be normalized here as well for the read path to match the write path.
134+
if (journey.datedServiceJourneyId() != null) {
135+
return resolveId(journey.datedServiceJourneyId());
135136
}
136137

137138
return null;

application/src/main/java/org/opentripplanner/updater/trip/siri/EstimatedVehicleJourneyWrapper.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,15 @@ final class EstimatedVehicleJourneyWrapper {
2020
private final EstimatedVehicleJourney journey;
2121
private final List<CallWrapper> calls;
2222

23+
@Nullable
24+
private final EstimatedVehicleJourneyCodeAdapter codeAdapter;
25+
2326
private EstimatedVehicleJourneyWrapper(EstimatedVehicleJourney journey, List<CallWrapper> calls) {
2427
this.journey = journey;
2528
this.calls = calls;
29+
this.codeAdapter = journey.getEstimatedVehicleJourneyCode() != null
30+
? new EstimatedVehicleJourneyCodeAdapter(journey.getEstimatedVehicleJourneyCode())
31+
: null;
2632
}
2733

2834
/* Construction and validation */
@@ -84,11 +90,25 @@ boolean isPredictionInaccurate() {
8490
/* Trip identification */
8591

8692
/**
87-
* A code used to build the id of an extra-journey.
93+
* The service journey id of an extra journey, derived from the EstimatedVehicleJourneyCode and
94+
* normalized to the {@code ServiceJourney} entity type (used to identify the added {@link
95+
* org.opentripplanner.transit.model.timetable.Trip}). {@code null} when the journey carries no
96+
* code.
97+
*/
98+
@Nullable
99+
String serviceJourneyId() {
100+
return codeAdapter != null ? codeAdapter.getServiceJourneyId() : null;
101+
}
102+
103+
/**
104+
* The dated service journey id of an extra journey, derived from the EstimatedVehicleJourneyCode
105+
* and normalized to the {@code DatedServiceJourney} entity type (used to identify the added {@link
106+
* org.opentripplanner.transit.model.timetable.TripOnServiceDate}). {@code null} when the journey
107+
* carries no code.
88108
*/
89109
@Nullable
90-
String estimatedVehicleJourneyCode() {
91-
return journey.getEstimatedVehicleJourneyCode();
110+
String datedServiceJourneyId() {
111+
return codeAdapter != null ? codeAdapter.getDatedServiceJourneyId() : null;
92112
}
93113

94114
/**

application/src/test/java/org/opentripplanner/updater/trip/siri/EntityResolverTest.java

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
44

5+
import java.time.LocalDate;
6+
import java.time.ZoneId;
57
import java.util.List;
68
import java.util.Map;
9+
import java.util.function.UnaryOperator;
710
import org.junit.jupiter.api.Test;
11+
import org.opentripplanner.LocalTimeParser;
812
import org.opentripplanner.core.model.id.FeedScopedId;
913
import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
1014
import org.opentripplanner.transit.model.site.RegularStop;
1115
import org.opentripplanner.transit.service.DefaultTransitService;
1216
import org.opentripplanner.transit.service.SiteRepository;
1317
import org.opentripplanner.transit.service.TimetableRepository;
18+
import org.opentripplanner.updater.spi.UpdateException;
1419

1520
class EntityResolverTest {
1621

@@ -22,6 +27,10 @@ class EntityResolverTest {
2227
.build();
2328
private static final String FEED_ID = STOP_1.getId().getFeedId();
2429
private static final FeedScopedId SSP_ID = new FeedScopedId(FEED_ID, "ssp-1");
30+
private static final LocalTimeParser TIME_PARSER = new LocalTimeParser(
31+
ZoneId.of("Europe/Oslo"),
32+
LocalDate.of(2024, 5, 7)
33+
);
2534

2635
@Test
2736
void resolveScheduledStopPointId() {
@@ -51,4 +60,66 @@ void scheduledStopPointTakesPrecedence() {
5160
assertEquals(STOP_2, resolver.resolveQuay(SSP_ID.getId()));
5261
assertEquals(STOP_1, resolver.resolveQuay(STOP_1.getId().getId()));
5362
}
63+
64+
/**
65+
* When the dated service journey is resolved from the EstimatedVehicleJourneyCode, the code must
66+
* be normalized to a DatedServiceJourney id, matching the id under which {@link AddedTripBuilder}
67+
* registers the added TripOnServiceDate. A code supplied in ServiceJourney form must be swapped.
68+
*/
69+
@Test
70+
void resolveDatedServiceJourneyIdFromServiceJourneyCode() throws UpdateException {
71+
var resolver = newResolver();
72+
var journey = journey(builder ->
73+
builder.withEstimatedVehicleJourneyCode("RUT:ServiceJourney:1234")
74+
);
75+
76+
assertEquals(
77+
new FeedScopedId(FEED_ID, "RUT:DatedServiceJourney:1234"),
78+
resolver.resolveDatedServiceJourneyId(journey)
79+
);
80+
}
81+
82+
@Test
83+
void resolveDatedServiceJourneyIdFromDatedServiceJourneyCode() throws UpdateException {
84+
var resolver = newResolver();
85+
var journey = journey(builder ->
86+
builder.withEstimatedVehicleJourneyCode("RUT:DatedServiceJourney:1234")
87+
);
88+
89+
assertEquals(
90+
new FeedScopedId(FEED_ID, "RUT:DatedServiceJourney:1234"),
91+
resolver.resolveDatedServiceJourneyId(journey)
92+
);
93+
}
94+
95+
/**
96+
* A DatedVehicleJourneyRef takes precedence over the EstimatedVehicleJourneyCode and is resolved
97+
* verbatim, without entity-type normalization.
98+
*/
99+
@Test
100+
void resolveDatedServiceJourneyIdFromDatedVehicleJourneyRef() throws UpdateException {
101+
var resolver = newResolver();
102+
var journey = journey(builder ->
103+
builder
104+
.withDatedVehicleJourneyRef("RUT:DatedServiceJourney:5678")
105+
.withEstimatedVehicleJourneyCode("RUT:ServiceJourney:1234")
106+
);
107+
108+
assertEquals(
109+
new FeedScopedId(FEED_ID, "RUT:DatedServiceJourney:5678"),
110+
resolver.resolveDatedServiceJourneyId(journey)
111+
);
112+
}
113+
114+
private static EntityResolver newResolver() {
115+
var transitService = new DefaultTransitService(new TimetableRepository());
116+
return new EntityResolver(transitService, FEED_ID);
117+
}
118+
119+
private static EstimatedVehicleJourneyWrapper journey(UnaryOperator<SiriEtBuilder> configure)
120+
throws UpdateException {
121+
return EstimatedVehicleJourneyWrapper.of(
122+
configure.apply(new SiriEtBuilder(TIME_PARSER)).buildEstimatedVehicleJourney()
123+
);
124+
}
54125
}

application/src/test/java/org/opentripplanner/updater/trip/siri/EstimatedVehicleJourneyWrapperTest.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,29 @@ void datedVehicleJourneyRef() {
121121
}
122122

123123
@Test
124-
void estimatedVehicleJourneyCode() {
125-
var journey = builder().withEstimatedVehicleJourneyCode("EVJ:1").buildEstimatedVehicleJourney();
124+
void serviceJourneyId() {
125+
var journey = builder()
126+
.withEstimatedVehicleJourneyCode("RUT:DatedServiceJourney:1234")
127+
.buildEstimatedVehicleJourney();
128+
129+
// The EstimatedVehicleJourneyCode is normalized to the ServiceJourney entity type.
130+
assertEquals(
131+
"RUT:ServiceJourney:1234",
132+
EstimatedVehicleJourneyWrapper.of(journey).serviceJourneyId()
133+
);
134+
}
126135

127-
assertEquals("EVJ:1", EstimatedVehicleJourneyWrapper.of(journey).estimatedVehicleJourneyCode());
136+
@Test
137+
void datedServiceJourneyId() {
138+
var journey = builder()
139+
.withEstimatedVehicleJourneyCode("RUT:ServiceJourney:1234")
140+
.buildEstimatedVehicleJourney();
141+
142+
// The EstimatedVehicleJourneyCode is normalized to the DatedServiceJourney entity type.
143+
assertEquals(
144+
"RUT:DatedServiceJourney:1234",
145+
EstimatedVehicleJourneyWrapper.of(journey).datedServiceJourneyId()
146+
);
128147
}
129148

130149
@Test
@@ -243,7 +262,8 @@ void accessorsAreNullSafeOnMinimalJourney() {
243262
assertNull(wrapper.lineRef());
244263
assertNull(wrapper.operatorRef());
245264
assertNull(wrapper.datedVehicleJourneyRef());
246-
assertNull(wrapper.estimatedVehicleJourneyCode());
265+
assertNull(wrapper.serviceJourneyId());
266+
assertNull(wrapper.datedServiceJourneyId());
247267
assertNull(wrapper.vehicleJourneyIdAndServiceDate());
248268
assertNull(wrapper.internalPlanningCode());
249269
assertNull(wrapper.replacedDatedVehicleJourneyRef());

0 commit comments

Comments
 (0)