Skip to content

Commit

Permalink
Merge remote-tracking branch 'entur/more_filters' into otp2_entur_dev…
Browse files Browse the repository at this point in the history
…elop
  • Loading branch information
t2gran committed Nov 20, 2024
2 parents fcc9c09 + b382642 commit ae901b1
Show file tree
Hide file tree
Showing 19 changed files with 640 additions and 186 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@
import org.opentripplanner.routing.graphfinder.PlaceAtDistance;
import org.opentripplanner.routing.graphfinder.PlaceType;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace;
import org.opentripplanner.transit.api.model.CriteriaCollection;
import org.opentripplanner.transit.api.request.TripRequest;
import org.opentripplanner.transit.model.basic.TransitMode;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.opentripplanner.transit.model.network.Route;
Expand Down Expand Up @@ -1264,76 +1266,64 @@ private GraphQLSchema create() {
GraphQLFieldDefinition
.newFieldDefinition()
.name("serviceJourneys")
.description("Get all service journeys")
.description("Get all _service journeys_")
.withDirective(TransmodelDirectives.TIMING_DATA)
.type(new GraphQLNonNull(new GraphQLList(serviceJourneyType)))
.argument(
GraphQLArgument
.newArgument()
.name("lines")
.description("Set of ids of lines to fetch serviceJourneys for.")
.description("Set of ids of _lines_ to fetch _service journeys_ for.")
.type(new GraphQLList(Scalars.GraphQLID))
.build()
)
.argument(
GraphQLArgument
.newArgument()
.name("privateCodes")
.description("Set of ids of private codes to fetch serviceJourneys for.")
.description("Set of ids of _private codes_ to fetch _service journeys_ for.")
.type(new GraphQLList(Scalars.GraphQLString))
.build()
)
.argument(
GraphQLArgument
.newArgument()
.name("activeDates")
.description("Set of ids of active dates to fetch serviceJourneys for.")
.description("Set of _operating days_ to fetch _service journeys_ for.")
.type(new GraphQLList(TransmodelScalars.DATE_SCALAR))
.build()
)
.argument(
GraphQLArgument
.newArgument()
.name("authorities")
.description("Set of ids of authorities to fetch serviceJourneys for.")
.description("Set of ids of _authorities_ to fetch _service journeys_ for.")
.type(new GraphQLList(Scalars.GraphQLString))
.build()
)
.dataFetcher(environment -> {
List<FeedScopedId> lineIds = mapIDsToDomainNullSafe(
environment.getArgumentOrDefault("lines", List.of())
var authorities = CriteriaCollection.ofEmptyIsEverything(
mapIDsToDomainNullSafe(environment.getArgument("authorities"))
);
List<String> privateCodes = environment.getArgumentOrDefault("privateCodes", List.of());
List<LocalDate> activeServiceDates = environment.getArgumentOrDefault(
"activeDates",
List.of()
var lineIds = CriteriaCollection.ofEmptyIsEverything(
mapIDsToDomainNullSafe(environment.getArgument("lines"))
);
var privateCodes = CriteriaCollection.ofEmptyIsEverything(
environment.<List<String>>getArgument("privateCodes")
);
var activeServiceDates = CriteriaCollection.ofEmptyIsEverything(
environment.<List<LocalDate>>getArgument("activeDates")
);

// TODO OTP2 - Use FeedScoped ID
List<String> authorities = environment.getArgumentOrDefault("authorities", List.of());
TransitService transitService = GqlUtil.getTransitService(environment);
return transitService
.getAllTrips()
.stream()
.filter(t -> lineIds.isEmpty() || lineIds.contains(t.getRoute().getId()))
.filter(t ->
privateCodes.isEmpty() || privateCodes.contains(t.getNetexInternalPlanningCode())
)
.filter(t ->
authorities.isEmpty() ||
authorities.contains(t.getRoute().getAgency().getId().getId())
)
.filter(t ->
(
activeServiceDates.isEmpty() ||
transitService
.getCalendarService()
.getServiceDatesForServiceId(t.getServiceId())
.stream()
.anyMatch(activeServiceDates::contains)
)
)
.collect(Collectors.toList());
TripRequest tripRequest = TripRequest
.of()
.withAgencies(authorities)
.withRoutes(lineIds)
.withNetexInternalPlanningCodes(privateCodes)
.withServiceDates(activeServiceDates)
.build();

return GqlUtil.getTransitService(environment).getTrips(tripRequest);
})
.build()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.opentripplanner.apis.transmodel.model.EnumTypes;
import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars;
import org.opentripplanner.apis.transmodel.support.GqlUtil;
import org.opentripplanner.transit.api.model.CriteriaCollection;
import org.opentripplanner.transit.api.request.TripOnServiceDateRequest;
import org.opentripplanner.transit.api.request.TripOnServiceDateRequestBuilder;
import org.opentripplanner.transit.model.framework.FeedScopedId;
Expand Down Expand Up @@ -94,26 +95,40 @@ public static GraphQLFieldDefinition createQuery(GraphQLOutputType datedServiceJ
)
.dataFetcher(environment -> {
// The null safety checks are not needed here - they are taken care of by the request
// object, but reuse let's use the mapping method and leave this improvement until all APIs
// object, but let's use the mapping method and leave this improvement until all APIs
// are pushing this check into the domain request.
var authorities = mapIDsToDomainNullSafe(environment.getArgument("authorities"));
var lines = mapIDsToDomainNullSafe(environment.getArgument("lines"));
var serviceJourneys = mapIDsToDomainNullSafe(environment.getArgument("serviceJourneys"));
var replacementFor = mapIDsToDomainNullSafe(environment.getArgument("replacementFor"));
var privateCodes = environment.<List<String>>getArgument("privateCodes");
var operatingDays = environment.<List<LocalDate>>getArgument("operatingDays");
var alterations = environment.<List<TripAlteration>>getArgument("alterations");
var authorities = CriteriaCollection.ofEmptyIsEverything(
mapIDsToDomainNullSafe(environment.getArgument("authorities"))
);
var lines = CriteriaCollection.ofEmptyIsEverything(
mapIDsToDomainNullSafe(environment.getArgument("lines"))
);
var serviceJourneys = CriteriaCollection.ofEmptyIsEverything(
mapIDsToDomainNullSafe(environment.getArgument("serviceJourneys"))
);
var replacementFor = CriteriaCollection.ofEmptyIsEverything(
mapIDsToDomainNullSafe(environment.getArgument("replacementFor"))
);
var privateCodes = CriteriaCollection.ofEmptyIsEverything(
environment.<List<String>>getArgument("privateCodes")
);
var operatingDays = CriteriaCollection.ofEmptyIsEverything(
environment.<List<LocalDate>>getArgument("operatingDays")
);
var alterations = CriteriaCollection.ofEmptyIsEverything(
environment.<List<TripAlteration>>getArgument("alterations")
);

TripOnServiceDateRequestBuilder tripOnServiceDateRequestBuilder = TripOnServiceDateRequest
.of()
.withOperatingDays(operatingDays)
.withAuthorities(authorities)
.withLines(lines)
.withServiceDates(operatingDays)
.withAgencies(authorities)
.withRoutes(lines)
.withServiceJourneys(serviceJourneys)
.withReplacementFor(replacementFor);

tripOnServiceDateRequestBuilder =
tripOnServiceDateRequestBuilder.withPrivateCodes(privateCodes);
tripOnServiceDateRequestBuilder.withNetexInternalPlanningCodes(privateCodes);

tripOnServiceDateRequestBuilder =
tripOnServiceDateRequestBuilder.withAlterations(alterations);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.opentripplanner.transit.api.model;

import com.beust.jcommander.internal.Nullable;
import java.util.Collection;
import java.util.NoSuchElementException;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.opentripplanner.transit.service.TransitService;

/**
* CriteriaCollection is meant to be used when filtering results from {@link TransitService}.
* </p>
* This abstraction over the Collection type lets us keep filter specific functionality separate
* from interpretation of various states of a collection. For instance in which case the criteria
* should match all entities it's meant to filter.
* @param <E> - The type of the criteria. Typically, String or {@link FeedScopedId}.
*/
public class CriteriaCollection<E> {

private Collection<E> criteria;

CriteriaCollection(Collection<E> criteria) {
this.criteria = criteria;
}

public static <E> CriteriaCollection<E> ofEmptyIsEverything(@Nullable Collection<E> criteria) {
return new CriteriaCollection<>(criteria);
}

public static <E> CriteriaCollection<E> ofEmptyIsEverything(
@Nullable CriteriaCollection<E> criteria
) {
if (criteria == null) {
return new CriteriaCollection<>(null);
}
return criteria;
}

public boolean includeEverything() {
return criteria == null || criteria.isEmpty();
}

public Collection<E> get() {
if (criteria == null) {
throw new NoSuchElementException(
"No values present, use matchesAll() before calling this method."
);
}
return criteria;
}
}
Original file line number Diff line number Diff line change
@@ -1,77 +1,78 @@
package org.opentripplanner.transit.api.request;

import java.time.LocalDate;
import java.util.List;
import org.opentripplanner.transit.api.model.CriteriaCollection;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.opentripplanner.transit.model.timetable.TripAlteration;
import org.opentripplanner.utils.collection.ListUtils;
import org.opentripplanner.transit.model.timetable.TripOnServiceDate;

/*
/**
* A request for trips on a specific service date.
*
* This request is used to retrieve TripsOnServiceDates that match the provided criteria.
* </p>
* This request is used to retrieve {@link TripOnServiceDate}s that match the provided criteria.
* At least one operatingDay must be provided.
*/
public class TripOnServiceDateRequest {

private final List<LocalDate> operatingDays;
private final List<FeedScopedId> authorities;
private final List<FeedScopedId> lines;
private final List<FeedScopedId> serviceJourneys;
private final List<FeedScopedId> replacementFor;
private final List<String> privateCodes;
private final List<TripAlteration> alterations;
private final CriteriaCollection<LocalDate> serviceDates;
private final CriteriaCollection<FeedScopedId> agencies;
private final CriteriaCollection<FeedScopedId> routes;
private final CriteriaCollection<FeedScopedId> serviceJourneys;
private final CriteriaCollection<FeedScopedId> replacementFor;
private final CriteriaCollection<String> netexInternalPlanningCodes;
private final CriteriaCollection<TripAlteration> alterations;

protected TripOnServiceDateRequest(
List<LocalDate> operatingDays,
List<FeedScopedId> authorities,
List<FeedScopedId> lines,
List<FeedScopedId> serviceJourneys,
List<FeedScopedId> replacementFor,
List<String> privateCodes,
List<TripAlteration> alterations
CriteriaCollection<LocalDate> serviceDates,
CriteriaCollection<FeedScopedId> agencies,
CriteriaCollection<FeedScopedId> routes,
CriteriaCollection<FeedScopedId> serviceJourneys,
CriteriaCollection<FeedScopedId> replacementFor,
CriteriaCollection<String> netexInternalPlanningCodes,
CriteriaCollection<TripAlteration> alterations
) {
if (operatingDays == null || operatingDays.isEmpty()) {
if (serviceDates.get() == null || serviceDates.get().isEmpty()) {
throw new IllegalArgumentException("operatingDays must have at least one date");
}
this.operatingDays = ListUtils.nullSafeImmutableList(operatingDays);
this.authorities = ListUtils.nullSafeImmutableList(authorities);
this.lines = ListUtils.nullSafeImmutableList(lines);
this.serviceJourneys = ListUtils.nullSafeImmutableList(serviceJourneys);
this.replacementFor = ListUtils.nullSafeImmutableList(replacementFor);
this.privateCodes = ListUtils.nullSafeImmutableList(privateCodes);
this.alterations = ListUtils.nullSafeImmutableList(alterations);
this.serviceDates = CriteriaCollection.ofEmptyIsEverything(serviceDates);
this.agencies = CriteriaCollection.ofEmptyIsEverything(agencies);
this.routes = CriteriaCollection.ofEmptyIsEverything(routes);
this.serviceJourneys = CriteriaCollection.ofEmptyIsEverything(serviceJourneys);
this.replacementFor = CriteriaCollection.ofEmptyIsEverything(replacementFor);
this.netexInternalPlanningCodes =
CriteriaCollection.ofEmptyIsEverything(netexInternalPlanningCodes);
this.alterations = CriteriaCollection.ofEmptyIsEverything(alterations);
}

public static TripOnServiceDateRequestBuilder of() {
return new TripOnServiceDateRequestBuilder();
}

public List<FeedScopedId> authorities() {
return authorities;
public CriteriaCollection<FeedScopedId> agencies() {
return agencies;
}

public List<FeedScopedId> lines() {
return lines;
public CriteriaCollection<FeedScopedId> routes() {
return routes;
}

public List<FeedScopedId> serviceJourneys() {
public CriteriaCollection<FeedScopedId> serviceJourneys() {
return serviceJourneys;
}

public List<FeedScopedId> replacementFor() {
public CriteriaCollection<FeedScopedId> replacementFor() {
return replacementFor;
}

public List<String> privateCodes() {
return privateCodes;
public CriteriaCollection<String> netexInternalPlanningCodes() {
return netexInternalPlanningCodes;
}

public List<TripAlteration> alterations() {
public CriteriaCollection<TripAlteration> alterations() {
return alterations;
}

public List<LocalDate> operatingDays() {
return operatingDays;
public CriteriaCollection<LocalDate> serviceDates() {
return serviceDates;
}
}
Loading

0 comments on commit ae901b1

Please sign in to comment.