|
5 | 5 | import com.google.common.flogger.FluentLogger; |
6 | 6 | import com.vladsch.flexmark.util.misc.Pair; |
7 | 7 | import java.time.LocalDate; |
8 | | -import java.time.format.DateTimeFormatter; |
9 | 8 | import java.util.*; |
10 | 9 | import java.util.function.Function; |
| 10 | +import java.util.stream.Stream; |
11 | 11 | import org.mobilitydata.gtfsvalidator.performance.MemoryUsage; |
12 | 12 | import org.mobilitydata.gtfsvalidator.performance.MemoryUsageRegister; |
13 | 13 | import org.mobilitydata.gtfsvalidator.reportsummary.AgencyMetadata; |
14 | 14 | import org.mobilitydata.gtfsvalidator.reportsummary.JsonReportCounts; |
15 | 15 | import org.mobilitydata.gtfsvalidator.reportsummary.JsonReportFeedInfo; |
16 | 16 | import org.mobilitydata.gtfsvalidator.table.*; |
17 | | -import org.mobilitydata.gtfsvalidator.util.CalendarUtil; |
18 | | -import org.mobilitydata.gtfsvalidator.util.ServicePeriod; |
19 | 17 |
|
20 | 18 | public class FeedMetadata { |
21 | 19 |
|
@@ -80,16 +78,28 @@ public static FeedMetadata from(GtfsFeedContainer feedContainer, ImmutableSet<St |
80 | 78 | feedMetadata.loadAgencyData(agencyTableOptional.get()); |
81 | 79 | } |
82 | 80 |
|
83 | | - if (feedContainer.getTableForFilename(GtfsTrip.FILENAME).isPresent() |
84 | | - && (feedContainer.getTableForFilename(GtfsCalendar.FILENAME).isPresent() |
85 | | - || feedContainer.getTableForFilename(GtfsCalendarDate.FILENAME).isPresent())) { |
| 81 | + Optional<GtfsTripTableContainer> tripTableContainer = |
| 82 | + feedContainer |
| 83 | + .getTableForFilename(GtfsTrip.FILENAME) |
| 84 | + .filter(GtfsEntityContainer::isParsedSuccessfully) |
| 85 | + .map(c -> (GtfsTripTableContainer) c); |
| 86 | + |
| 87 | + Optional<GtfsCalendarTableContainer> calendarTableContainer = |
| 88 | + feedContainer |
| 89 | + .getTableForFilename(GtfsCalendar.FILENAME) |
| 90 | + .filter(GtfsEntityContainer::isParsedSuccessfully) |
| 91 | + .map(c -> (GtfsCalendarTableContainer) c); |
| 92 | + |
| 93 | + Optional<GtfsCalendarDateTableContainer> calendarDateTableContainer = |
| 94 | + feedContainer |
| 95 | + .getTableForFilename(GtfsCalendarDate.FILENAME) |
| 96 | + .filter(GtfsEntityContainer::isParsedSuccessfully) |
| 97 | + .map(c -> (GtfsCalendarDateTableContainer) c); |
| 98 | + |
| 99 | + if (tripTableContainer.isPresent() |
| 100 | + && (calendarTableContainer.isPresent() || calendarDateTableContainer.isPresent())) { |
86 | 101 | feedMetadata.loadServiceWindow( |
87 | | - (GtfsTableContainer<GtfsTrip, ?>) |
88 | | - feedContainer.getTableForFilename(GtfsTrip.FILENAME).get(), |
89 | | - (GtfsTableContainer<GtfsCalendar, ?>) |
90 | | - feedContainer.getTableForFilename(GtfsCalendar.FILENAME).get(), |
91 | | - (GtfsTableContainer<GtfsCalendarDate, ?>) |
92 | | - feedContainer.getTableForFilename(GtfsCalendarDate.FILENAME).get()); |
| 102 | + tripTableContainer.get(), calendarTableContainer, calendarDateTableContainer); |
93 | 103 | } |
94 | 104 |
|
95 | 105 | feedMetadata.loadSpecFeatures(feedContainer); |
@@ -726,129 +736,44 @@ private String checkLocalDate(LocalDate localDate) { |
726 | 736 | /** |
727 | 737 | * Loads the service date range by determining the earliest start date and the latest end date for |
728 | 738 | * all services referenced with a trip\_id in `trips.txt`. It handles three cases: 1. When only |
729 | | - * `calendars.txt` is used. 2. When only `calendar\_dates.txt` is used. 3. When both |
730 | | - * `calendars.txt` and `calendar\_dates.txt` are used. |
| 739 | + * `calendar.txt` is used. 2. When only `calendar\_dates.txt` is used. 3. When both `calendar.txt` |
| 740 | + * and `calendar\_dates.txt` are used. |
731 | 741 | * |
732 | 742 | * @param tripContainer the container for `trips.txt` data |
733 | | - * @param calendarTable the container for `calendars.txt` data |
| 743 | + * @param calendarTable the container for `calendar.txt` data |
734 | 744 | * @param calendarDateTable the container for `calendar\_dates.txt` data |
735 | 745 | */ |
736 | 746 | public void loadServiceWindow( |
737 | | - GtfsTableContainer<GtfsTrip, ?> tripContainer, |
738 | | - GtfsTableContainer<GtfsCalendar, ?> calendarTable, |
739 | | - GtfsTableContainer<GtfsCalendarDate, ?> calendarDateTable) { |
740 | | - List<GtfsTrip> trips = tripContainer.getEntities(); |
741 | | - |
| 747 | + GtfsTripTableContainer tripContainer, |
| 748 | + Optional<GtfsCalendarTableContainer> calendarTable, |
| 749 | + Optional<GtfsCalendarDateTableContainer> calendarDateTable) { |
742 | 750 | LocalDate earliestStartDate = null; |
743 | 751 | LocalDate latestEndDate = null; |
744 | 752 | try { |
745 | | - if ((calendarDateTable == null) && (calendarTable != null)) { |
746 | | - // When only calendars.txt is used |
747 | | - List<GtfsCalendar> calendars = calendarTable.getEntities(); |
748 | | - for (GtfsTrip trip : trips) { |
749 | | - String serviceId = trip.serviceId(); |
750 | | - for (GtfsCalendar calendar : calendars) { |
751 | | - if (calendar.serviceId().equals(serviceId)) { |
752 | | - LocalDate startDate = calendar.startDate().getLocalDate(); |
753 | | - LocalDate endDate = calendar.endDate().getLocalDate(); |
754 | | - if (startDate != null || endDate != null) { |
755 | | - if (startDate.toString().equals(LocalDate.EPOCH.toString()) |
756 | | - || endDate.toString().equals(LocalDate.EPOCH.toString())) { |
757 | | - continue; |
758 | | - } |
759 | | - if (earliestStartDate == null || startDate.isBefore(earliestStartDate)) { |
760 | | - earliestStartDate = startDate; |
761 | | - } |
762 | | - if (latestEndDate == null || endDate.isAfter(latestEndDate)) { |
763 | | - latestEndDate = endDate; |
764 | | - } |
765 | | - } |
766 | | - } |
767 | | - } |
768 | | - } |
769 | | - } else if ((calendarDateTable != null) && (calendarTable == null)) { |
770 | | - // When only calendar_dates.txt is used |
771 | | - List<GtfsCalendarDate> calendarDates = calendarDateTable.getEntities(); |
772 | | - for (GtfsTrip trip : trips) { |
773 | | - String serviceId = trip.serviceId(); |
774 | | - for (GtfsCalendarDate calendarDate : calendarDates) { |
775 | | - if (calendarDate.serviceId().equals(serviceId)) { |
776 | | - LocalDate date = calendarDate.date().getLocalDate(); |
777 | | - if (date != null && !date.toString().equals(LocalDate.EPOCH.toString())) { |
778 | | - if (earliestStartDate == null || date.isBefore(earliestStartDate)) { |
779 | | - earliestStartDate = date; |
780 | | - } |
781 | | - if (latestEndDate == null || date.isAfter(latestEndDate)) { |
782 | | - latestEndDate = date; |
783 | | - } |
784 | | - } |
785 | | - } |
786 | | - } |
787 | | - } |
788 | | - } else if ((calendarTable != null) && (calendarDateTable != null)) { |
789 | | - // When both calendars.txt and calendar_dates.txt are used |
790 | | - Map<String, ServicePeriod> servicePeriods = |
791 | | - CalendarUtil.buildServicePeriodMap( |
792 | | - (GtfsCalendarTableContainer) calendarTable, |
793 | | - (GtfsCalendarDateTableContainer) calendarDateTable); |
794 | | - List<LocalDate> removedDates = new ArrayList<>(); |
795 | | - for (GtfsTrip trip : trips) { |
796 | | - String serviceId = trip.serviceId(); |
797 | | - ServicePeriod servicePeriod = servicePeriods.get(serviceId); |
798 | | - LocalDate startDate = servicePeriod.getServiceStart(); |
799 | | - LocalDate endDate = servicePeriod.getServiceEnd(); |
800 | | - if (startDate != null && endDate != null) { |
801 | | - if (startDate.toString().equals(LocalDate.EPOCH.toString()) |
802 | | - || endDate.toString().equals(LocalDate.EPOCH.toString())) { |
803 | | - continue; |
804 | | - } |
805 | | - if (earliestStartDate == null || startDate.isBefore(earliestStartDate)) { |
806 | | - earliestStartDate = startDate; |
807 | | - } |
808 | | - if (latestEndDate == null || endDate.isAfter(latestEndDate)) { |
809 | | - latestEndDate = endDate; |
810 | | - } |
811 | | - } |
812 | | - removedDates.addAll(servicePeriod.getRemovedDays()); |
813 | | - } |
814 | | - |
815 | | - for (LocalDate date : removedDates) { |
816 | | - if (date.isEqual(earliestStartDate)) { |
817 | | - earliestStartDate = date.plusDays(1); |
818 | | - } |
819 | | - if (date.isEqual(latestEndDate)) { |
820 | | - latestEndDate = date.minusDays(1); |
821 | | - } |
822 | | - } |
| 753 | + Optional<ServiceWindow> serviceWindow = |
| 754 | + ServiceWindow.get(tripContainer, calendarTable, calendarDateTable); |
| 755 | + if (serviceWindow.isEmpty()) { |
| 756 | + logger.atWarning().log( |
| 757 | + "Could not compute service window. Check that `calendar.txt` and `calendar_dates.txt` contain data if they are present."); |
823 | 758 | } |
| 759 | + earliestStartDate = serviceWindow.map(ServiceWindow::startDate).orElse(null); |
| 760 | + latestEndDate = serviceWindow.map(ServiceWindow::endDate).orElse(null); |
824 | 761 | } catch (Exception e) { |
825 | 762 | logger.atSevere().withCause(e).log("Error while loading Service Window"); |
826 | 763 | } finally { |
827 | | - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy"); |
828 | | - if ((earliestStartDate == null) && (latestEndDate == null)) { |
829 | | - feedInfo.put(JsonReportFeedInfo.FEED_INFO_SERVICE_WINDOW, ""); |
830 | | - } else if (earliestStartDate == null && latestEndDate != null) { |
831 | | - feedInfo.put(JsonReportFeedInfo.FEED_INFO_SERVICE_WINDOW, latestEndDate.format(formatter)); |
832 | | - } else if (latestEndDate == null && earliestStartDate != null) { |
833 | | - if (earliestStartDate.isAfter(latestEndDate)) { |
834 | | - feedInfo.put(JsonReportFeedInfo.FEED_INFO_SERVICE_WINDOW, ""); |
835 | | - } else { |
836 | | - feedInfo.put( |
837 | | - JsonReportFeedInfo.FEED_INFO_SERVICE_WINDOW, earliestStartDate.format(formatter)); |
838 | | - } |
839 | | - } else { |
840 | | - StringBuilder serviceWindow = new StringBuilder(); |
841 | | - serviceWindow.append(earliestStartDate); |
842 | | - serviceWindow.append(" to "); |
843 | | - serviceWindow.append(latestEndDate); |
844 | | - feedInfo.put(JsonReportFeedInfo.FEED_INFO_SERVICE_WINDOW, serviceWindow.toString()); |
845 | | - } |
| 764 | + String serviceWindowStr = |
| 765 | + String.join( |
| 766 | + " to ", |
| 767 | + Stream.of(earliestStartDate, latestEndDate) |
| 768 | + .filter(Objects::nonNull) |
| 769 | + .map(LocalDate::toString) |
| 770 | + .toList()); |
| 771 | + feedInfo.put(JsonReportFeedInfo.FEED_INFO_SERVICE_WINDOW, serviceWindowStr); |
846 | 772 | feedInfo.put( |
847 | 773 | JsonReportFeedInfo.FEED_INFO_SERVICE_WINDOW_START, |
848 | | - earliestStartDate == null ? "" : earliestStartDate.toString()); |
| 774 | + Objects.toString(earliestStartDate, "")); |
849 | 775 | feedInfo.put( |
850 | | - JsonReportFeedInfo.FEED_INFO_SERVICE_WINDOW_END, |
851 | | - latestEndDate == null ? "" : latestEndDate.toString()); |
| 776 | + JsonReportFeedInfo.FEED_INFO_SERVICE_WINDOW_END, Objects.toString(latestEndDate, "")); |
852 | 777 | } |
853 | 778 | } |
854 | 779 |
|
|
0 commit comments