public void update(FeedMessage message) { alertPatchService.expire(patchIds); patchIds.clear(); for (FeedEntity entity : message.getEntityList()) { if (!entity.hasAlert()) { continue; } GtfsRealtime.Alert alert = entity.getAlert(); String id = entity.getId(); handleAlert(id, alert); } }
if (entity.hasIsDeleted()) { RuleUtils.addOccurrence(E039, "entity ID " + entity.getId() + " has is_deleted=" + entity.getIsDeleted(), errorListE039, _log);
RuleUtils.addOccurrence(W002, "entity ID " + entity.getId(), w002List, _log); } else { if (vehicleIds.contains(v.getVehicle().getId())) { RuleUtils.addOccurrence(E052, "entity ID " + entity.getId() + " has vehicle.id " + v.getVehicle().getId(), e052List, _log); } else { vehicleIds.add(v.getVehicle().getId());
AgencyAndId id = createId(entity.getId());
RuleUtils.addOccurrence(W005, "entity ID" + entity.getId() + "with trip_id " + vehiclePosition.getTrip().getTripId(), errorListW005, _log);
String entityId = entity.getId(); if (entity.hasTripUpdate()) { GtfsRealtime.TripUpdate tripUpdate = entity.getTripUpdate();
/** * Checks rule E035 - "GTFS-rt trip.trip_id does not belong to GTFS-rt trip.route_id in GTFS trips.txt", and adds any errors that are found to the provided error list * * @param entity entity which contains the specified trip * @param trip trip to examine to see if the trip_id belongs to the route_id * @param gtfsMetadata information about the GTFS dataset * @param errors list to add any errors for E034 to */ private void checkE035(GtfsRealtime.FeedEntity entity, GtfsRealtime.TripDescriptor trip, GtfsMetadata gtfsMetadata, List<OccurrenceModel> errors) { if (trip.hasTripId() && trip.hasRouteId()) { if (!gtfsMetadata.getRouteIds().contains(trip.getRouteId())) { // route_id isn't in GTFS data (which will be caught by E004) - return; return; } Trip gtfsTrip = gtfsMetadata.getTrips().get(trip.getTripId()); if (gtfsTrip == null) { // trip_id isn't in GTFS data (which will be caught by E003) - return; return; } String gtfsRouteId = gtfsTrip.getRoute().getId().getId(); if (!gtfsRouteId.equals(trip.getRouteId())) { RuleUtils.addOccurrence(E035, "GTFS-rt entity ID " + entity.getId() + " trip_id " + trip.getTripId() + " has route_id " + trip.getRouteId() + " but belongs to GTFS route_id " + gtfsRouteId, errors, _log); } } }
/** * Checks rule E033 - "Alert informed_entity does not have any specifiers" and adds * any errors that are found to the provided errors list * * @param entity feed entity to examine that contains an alert * @param entitySelector EntitySelector to examine for specifiers * @param errors list to add any errors for E033 to */ private void checkE033(GtfsRealtime.FeedEntity entity, GtfsRealtime.EntitySelector entitySelector, List<OccurrenceModel> errors) { GtfsRealtime.TripDescriptor trip = null; if (entitySelector.hasTrip()) { trip = entitySelector.getTrip(); } if (!entitySelector.hasAgencyId() && !entitySelector.hasRouteId() && !entitySelector.hasRouteType() && !entitySelector.hasStopId()) { // informed_entity isn't populated - check TripDescriptor if (trip == null || (!trip.hasTripId() && !trip.hasRouteId())) { RuleUtils.addOccurrence(E033, "alert ID " + entity.getId() + " informed_entity and informed_entity.trip do not not reference any agency, route, trip, or stop", errors, _log); } } }
/** * Validate Alert time ranges - E001 * * @param entity entity that has alerts to check * @param errors list to which any errors can be added */ private void checkAlertE001(GtfsRealtime.FeedEntity entity, List<OccurrenceModel> errors) { GtfsRealtime.Alert alert = entity.getAlert(); List<GtfsRealtime.TimeRange> activePeriods = alert.getActivePeriodList(); if (activePeriods != null) { for (GtfsRealtime.TimeRange range : activePeriods) { if (range.hasStart()) { if (!isPosix(range.getStart())) { RuleUtils.addOccurrence(E001, "alert in entity " + entity.getId() + " active_period.start " + range.getStart(), errors, _log); } } if (range.hasEnd()) { if (!isPosix(range.getEnd())) { RuleUtils.addOccurrence(E001, "alert in entity " + entity.getId() + " active_period.end " + range.getEnd(), errors, _log); } } } } } }
/** * Checks rule E030 - "GTFS-rt alert trip_id does not belong to GTFS-rt alert route_id in GTFS trips.txt" and adds * any errors that are found to the provided errors list * * @param entity feed entity to examine that contains an alert * @param entitySelector EntitySelector that has both a routeId and a tripDescriptor * @param gtfsMetadata metadata for the static GTFS data * @param errors list to add any errors for E030 to */ private void checkE030(GtfsRealtime.FeedEntity entity, GtfsRealtime.EntitySelector entitySelector, GtfsMetadata gtfsMetadata, List<OccurrenceModel> errors) { String routeId = entitySelector.getRouteId(); GtfsRealtime.TripDescriptor tripDescriptor = entitySelector.getTrip(); if (tripDescriptor.hasTripId()) { Trip gtfsTrip = gtfsMetadata.getTrips().get(tripDescriptor.getTripId()); if (gtfsTrip != null && !routeId.equals(gtfsTrip.getRoute().getId().getId())) { String prefix = "alert ID " + entity.getId() + " informed_entity.trip.trip_id " + tripDescriptor.getTripId() + " does not belong to informed_entity.route_id " + routeId + " (GTFS says it belongs to route_id " + gtfsTrip.getRoute().getId().getId() + ")"; RuleUtils.addOccurrence(E030, prefix, errors, _log); } } }
/** * <code>required string id = 1;</code> * * <pre> * The ids are used only to provide incrementality support. The id should be * unique within a FeedMessage. Consequent FeedMessages may contain * FeedEntities with the same id. In case of a DIFFERENTIAL update the new * FeedEntity with some id will replace the old FeedEntity with the same id * (or delete it - see is_deleted below). * The actual GTFS entities (e.g. stations, routes, trips) referenced by the * feed must be specified by explicit selectors (see EntitySelector below for * more info). * </pre> */ public Builder clearId() { bitField0_ = (bitField0_ & ~0x00000001); id_ = getDefaultInstance().getId(); onChanged(); return this; } /**
/** * Checks rule E031 - "Alert informed_entity.route_id does not match informed_entity.trip.route_id" and adds * any errors that are found to the provided errors list * * @param entity feed entity to examine that contains an alert * @param entitySelector EntitySelector that has both a routeId and a tripDescriptor * @param errors list to add any errors for E031 to */ private void checkE031(GtfsRealtime.FeedEntity entity, GtfsRealtime.EntitySelector entitySelector, List<OccurrenceModel> errors) { if (entitySelector.getTrip().hasRouteId()) { String routeId = entitySelector.getRouteId(); if (!entitySelector.getTrip().getRouteId().equals(routeId)) { RuleUtils.addOccurrence(E031, "alert ID " + entity.getId() + " informed_entity.route_id " + routeId + " does not equal informed_entity.trip.route_id " + entitySelector.getTrip().getRouteId(), errors, _log); } } }
/** * Returns the vehicle id for the given VehiclePosition if one exists, if not the entity ID is returned in the format * "vehicle.id 1234" or "entity ID 4321". * * @param entity the entity that the VehiclePosition belongs to * @param vehiclePosition the VehiclePosition to get the ID for * @return the vehicle.id for the given VehiclePosition if one exists, if not the entity ID is returned in the format "vehicle.id 1234" or "entity ID 4321". */ public static String getVehicleId(GtfsRealtime.FeedEntity entity, GtfsRealtime.VehiclePosition vehiclePosition) { if (!vehiclePosition.hasVehicle()) { return "entity ID " + entity.getId(); } return getVehicleId(entity, vehiclePosition.getVehicle()); }
/** * Checks rule E034 - "GTFS-rt agency_id does not exist in GTFS data", and adds any errors that are found to the provided error list * * @param entity feed entity to examine that contains an alert * @param entitySelector EntitySelector to examine for agency_id specifier * @param gtfsMetadata information about the GTFS dataset * @param errors list to add any errors for E034 to */ private void checkE034(GtfsRealtime.FeedEntity entity, GtfsRealtime.EntitySelector entitySelector, GtfsMetadata gtfsMetadata, List<OccurrenceModel> errors) { if (entitySelector.hasAgencyId()) { if (!gtfsMetadata.getAgencyIds().contains(entitySelector.getAgencyId())) { RuleUtils.addOccurrence(E034, "alert ID " + entity.getId() + " agency_id " + entitySelector.getAgencyId(), errors, _log); } } }
/** * Returns the trip_id for the given TripUpdate if one exists, if not the entity ID is returned in the format * "trip_id 1234" or "entity ID 4321". * * @param entity the entity that the TripUpdate belongs to * @param tripUpdate the tripUpdate to get the ID for * @return the trip_id for the given TripUpdate if one exists, if not the entity ID is returned in the format "trip_id 1234" or "entity ID 4321". */ public static String getTripId(GtfsRealtime.FeedEntity entity, GtfsRealtime.TripUpdate tripUpdate) { if (!tripUpdate.hasTrip()) { return "entity ID " + entity.getId(); } return getTripId(entity, tripUpdate.getTrip()); }
/** * Returns the vehicle.id for the given VehicleDescriptor if one exists, if not the entity ID is returned in the format * "vehicle.id 1234" or "entity ID 4321". * * @param entity the entity that the VehiclePosition belongs to * @param vehicleDescriptor the vehicleDescriptor to get the ID for * @return the vehicle.id for the given VehiclePosition if one exists, if not the entity ID is returned in the format "vehicle.id 1234" or "entity ID 4321". */ public static String getVehicleId(GtfsRealtime.FeedEntity entity, GtfsRealtime.VehicleDescriptor vehicleDescriptor) { return vehicleDescriptor.hasId() ? "vehicle.id " + vehicleDescriptor.getId() : "entity ID " + entity.getId(); }
/** * Returns the trip_id for the given TripDescriptor if one exists, if not the entity ID is returned in the format * "trip_id 1234" or "entity ID 4321". * * @param entity the entity that the TripUpdate belongs to * @param tripDescriptor the tripDescriptor to get the ID for * @return the trip_id for the given TripUpdate if one exists, if not the entity ID is returned in the format "trip_id 1234" or "entity ID 4321". */ public static String getTripId(GtfsRealtime.FeedEntity entity, GtfsRealtime.TripDescriptor tripDescriptor) { return tripDescriptor.hasTripId() ? "trip_id " + tripDescriptor.getTripId() : "entity ID " + entity.getId(); }
/** * Checks rule W006 - "trip missing trip_id", and adds any warnings that are found to the provided warning list * * @param entity entity which contains the specified trip * @param tripDescriptor trip to examine to see if it has trip_id * @param warnings list to add any warnings for W009 to */ private void checkW006(GtfsRealtime.FeedEntity entity, GtfsRealtime.TripDescriptor tripDescriptor, List<OccurrenceModel> warnings) { if (tripDescriptor != null && !tripDescriptor.hasTripId()) { RuleUtils.addOccurrence(W006, "entity ID " + entity.getId(), warnings, _log); } }
/** * <code>required string id = 1;</code> * * <pre> * The ids are used only to provide incrementality support. The id should be * unique within a FeedMessage. Consequent FeedMessages may contain * FeedEntities with the same id. In case of a DIFFERENTIAL update the new * FeedEntity with some id will replace the old FeedEntity with the same id * (or delete it - see is_deleted below). * The actual GTFS entities (e.g. stations, routes, trips) referenced by the * feed must be specified by explicit selectors (see EntitySelector below for * more info). * </pre> */ public Builder clearId() { bitField0_ = (bitField0_ & ~0x00000001); id_ = getDefaultInstance().getId(); onChanged(); return this; } /**