org.onebusaway.gtfs.impl.calendar.CalendarServiceDataFactoryImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of onebusaway-gtfs Show documentation
Show all versions of onebusaway-gtfs Show documentation
A Java library for reading and writing General Transit Feed Spec feeds
package org.onebusaway.gtfs.impl.calendar;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import org.onebusaway.gtfs.model.Agency;
import org.onebusaway.gtfs.model.AgencyAndId;
import org.onebusaway.gtfs.model.ServiceCalendar;
import org.onebusaway.gtfs.model.ServiceCalendarDate;
import org.onebusaway.gtfs.model.calendar.CalendarServiceData;
import org.onebusaway.gtfs.model.calendar.LocalizedServiceId;
import org.onebusaway.gtfs.model.calendar.ServiceDate;
import org.onebusaway.gtfs.services.GtfsRelationalDao;
import org.onebusaway.gtfs.services.calendar.CalendarServiceDataFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* We perform initial date calculations in the timezone of the host jvm, which
* may be different than the timezone of an agency with the specified service
* id. To my knowledge, the calculation should work the same, which is to say I
* can't immediately think of any cases where the service dates would be
* computed incorrectly.
*
* @author bdferris
*/
public class CalendarServiceDataFactoryImpl implements
CalendarServiceDataFactory {
private final Logger _log = LoggerFactory.getLogger(CalendarServiceDataFactoryImpl.class);
private GtfsRelationalDao _dao;
public CalendarServiceDataFactoryImpl() {
}
public CalendarServiceDataFactoryImpl(GtfsRelationalDao dao) {
_dao = dao;
}
public void setGtfsDao(GtfsRelationalDao dao) {
_dao = dao;
}
@Override
public CalendarServiceData createData() {
CalendarServiceData data = new CalendarServiceData();
setTimeZonesForAgencies(data);
Collection calendars = _dao.getAllCalendars();
Collection calendarDates = _dao.getAllCalendarDates();
Map calendarsByServiceId = getCalendarsByServiceId(calendars);
Map> calendarDatesByServiceId = getCalendarDatesByServiceId(calendarDates);
Set serviceIds = new HashSet();
serviceIds.addAll(calendarsByServiceId.keySet());
serviceIds.addAll(calendarDatesByServiceId.keySet());
int index = 0;
for (AgencyAndId serviceId : serviceIds) {
index++;
_log.info("serviceId=" + serviceId + " (" + index + "/"
+ serviceIds.size() + ")");
Set activeDates = new HashSet();
ServiceCalendar c = calendarsByServiceId.get(serviceId);
if (c != null)
addDatesFromCalendar(c, activeDates);
if (calendarDatesByServiceId.containsKey(serviceId)) {
for (ServiceCalendarDate cd : calendarDatesByServiceId.get(serviceId)) {
addAndRemoveDatesFromCalendarDate(cd, activeDates);
}
}
List serviceDates = new ArrayList(activeDates);
Collections.sort(serviceDates);
data.putServiceDatesForServiceId(serviceId, serviceDates);
List tripAgencyIds = _dao.getTripAgencyIdsReferencingServiceId(serviceId);
Set timeZones = new HashSet();
for (String tripAgencyId : tripAgencyIds) {
TimeZone timeZone = data.getTimeZoneForAgencyId(tripAgencyId);
timeZones.add(timeZone);
}
for (TimeZone timeZone : timeZones) {
List dates = new ArrayList(serviceDates.size());
for (ServiceDate serviceDate : serviceDates)
dates.add(serviceDate.getAsDate(timeZone));
LocalizedServiceId id = new LocalizedServiceId(serviceId, timeZone);
data.putDatesForLocalizedServiceId(id, dates);
}
}
return data;
}
private void setTimeZonesForAgencies(CalendarServiceData data) {
for (Agency agency : _dao.getAllAgencies()) {
TimeZone timeZone = TimeZone.getTimeZone(agency.getTimezone());
if (timeZone == null)
throw new IllegalStateException("unknown timezone=" + timeZone
+ " for agency " + agency.getName());
data.putTimeZoneForAgencyId(agency.getId(), timeZone);
}
}
private Map getCalendarsByServiceId(
Collection calendars) {
Map calendarsByServiceId = new HashMap();
for (ServiceCalendar c : calendars)
calendarsByServiceId.put(c.getServiceId(), c);
return calendarsByServiceId;
}
private Map> getCalendarDatesByServiceId(
Collection calendarDates) {
Map> calendarDatesByServiceId = new HashMap>();
for (ServiceCalendarDate calendarDate : calendarDates) {
List cds = calendarDatesByServiceId.get(calendarDate.getServiceId());
if (cds == null) {
cds = new ArrayList();
calendarDatesByServiceId.put(calendarDate.getServiceId(), cds);
}
cds.add(calendarDate);
}
return calendarDatesByServiceId;
}
private void addDatesFromCalendar(ServiceCalendar calendar,
Set activeDates) {
Date startDate = calendar.getStartDate().getAsDate();
Date endDate = calendar.getEndDate().getAsDate();
java.util.Calendar c = java.util.Calendar.getInstance();
c.setTime(startDate);
while (true) {
Date date = c.getTime();
if (date.after(endDate))
break;
int day = c.get(java.util.Calendar.DAY_OF_WEEK);
boolean active = false;
switch (day) {
case java.util.Calendar.MONDAY:
active = calendar.getMonday() == 1;
break;
case java.util.Calendar.TUESDAY:
active = calendar.getTuesday() == 1;
break;
case java.util.Calendar.WEDNESDAY:
active = calendar.getWednesday() == 1;
break;
case java.util.Calendar.THURSDAY:
active = calendar.getThursday() == 1;
break;
case java.util.Calendar.FRIDAY:
active = calendar.getFriday() == 1;
break;
case java.util.Calendar.SATURDAY:
active = calendar.getSaturday() == 1;
break;
case java.util.Calendar.SUNDAY:
active = calendar.getSunday() == 1;
break;
}
if (active) {
activeDates.add(new ServiceDate(c));
}
c.add(java.util.Calendar.DAY_OF_YEAR, 1);
}
}
private void addAndRemoveDatesFromCalendarDate(
ServiceCalendarDate calendarDate, Set activeDates) {
Date targetDate = calendarDate.getDate().getAsDate();
Calendar c = Calendar.getInstance();
c.setTime(targetDate);
switch (calendarDate.getExceptionType()) {
case ServiceCalendarDate.EXCEPTION_TYPE_ADD:
activeDates.add(new ServiceDate(c));
break;
case ServiceCalendarDate.EXCEPTION_TYPE_REMOVE:
activeDates.remove(new ServiceDate(c));
break;
default:
_log.warn("unknown CalendarDate exception type: "
+ calendarDate.getExceptionType());
break;
}
}
}