All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.onebusaway.gtfs.impl.GtfsRelationalDaoImpl Maven / Gradle / Ivy

There is a newer version: 1.3.4
Show newest version
/**
 * Copyright (C) 2011 Brian Ferris 
 * Copyright (C) 2011 Google, Inc.
 * Copyright (C) 2011 Laurent Gregoire 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.onebusaway.gtfs.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.onebusaway.csv_entities.exceptions.EntityInstantiationException;
import org.onebusaway.csv_entities.schema.BeanWrapper;
import org.onebusaway.csv_entities.schema.BeanWrapperFactory;
import org.onebusaway.gtfs.model.Agency;
import org.onebusaway.gtfs.model.AgencyAndId;
import org.onebusaway.gtfs.model.Frequency;
import org.onebusaway.gtfs.model.Route;
import org.onebusaway.gtfs.model.ServiceCalendar;
import org.onebusaway.gtfs.model.ServiceCalendarDate;
import org.onebusaway.gtfs.model.ShapePoint;
import org.onebusaway.gtfs.model.Stop;
import org.onebusaway.gtfs.model.StopTime;
import org.onebusaway.gtfs.model.Trip;
import org.onebusaway.gtfs.services.GtfsMutableRelationalDao;

/**
 * A in-memory implementation of GtfsRelationalDaoImpl. It's super fast for most
 * methods, but only if you have enough memory to load your entire GTFS into
 * memory.
 * 
 * @author bdferris
 * 
 */
public class GtfsRelationalDaoImpl extends GtfsDaoImpl implements
    GtfsMutableRelationalDao {

  private Map> _tripAgencyIdsByServiceId = null;

  private Map> _routesByAgency = null;

  private Map> _stopsByStation = null;
  
  private Map> _stopTimesByTrip = null;

  private Map> _stopTimesByStop = null;

  private Map> _tripsByRoute = null;

  private Map> _tripsByBlockId = null;

  private Map> _shapePointsByShapeId = null;

  private Map> _frequenciesByTrip = null;

  private Map> _calendarDatesByServiceId = null;

  private Map> _calendarsByServiceId = null;

  public void clearAllCaches() {
    _tripAgencyIdsByServiceId = clearMap(_tripAgencyIdsByServiceId);
    _routesByAgency = clearMap(_routesByAgency);
    _stopsByStation = clearMap(_stopsByStation);
    _stopTimesByTrip = clearMap(_stopTimesByTrip);
    _stopTimesByStop = clearMap(_stopTimesByStop);
    _tripsByRoute = clearMap(_tripsByRoute);
    _tripsByBlockId = clearMap(_tripsByBlockId);
    _shapePointsByShapeId = clearMap(_shapePointsByShapeId);
    _frequenciesByTrip = clearMap(_frequenciesByTrip);
    _calendarDatesByServiceId = clearMap(_calendarDatesByServiceId);
    _calendarsByServiceId = clearMap(_calendarsByServiceId);
  }

  @Override
  public List getTripAgencyIdsReferencingServiceId(AgencyAndId serviceId) {

    if (_tripAgencyIdsByServiceId == null) {

      Map> agencyIdsByServiceIds = new HashMap>();

      for (Trip trip : getAllTrips()) {
        AgencyAndId tripId = trip.getId();
        String tripAgencyId = tripId.getAgencyId();
        AgencyAndId tripServiceId = trip.getServiceId();
        Set agencyIds = agencyIdsByServiceIds.get(tripServiceId);
        if (agencyIds == null) {
          agencyIds = new HashSet();
          agencyIdsByServiceIds.put(tripServiceId, agencyIds);
        }
        agencyIds.add(tripAgencyId);
      }

      _tripAgencyIdsByServiceId = new HashMap>();

      for (Map.Entry> entry : agencyIdsByServiceIds.entrySet()) {
        AgencyAndId tripServiceId = entry.getKey();
        List agencyIds = new ArrayList(entry.getValue());
        Collections.sort(agencyIds);
        _tripAgencyIdsByServiceId.put(tripServiceId, agencyIds);
      }
    }

    List agencyIds = _tripAgencyIdsByServiceId.get(serviceId);
    if (agencyIds == null)
      agencyIds = new ArrayList();
    return agencyIds;
  }

  @Override
  public List getRoutesForAgency(Agency agency) {
    if (_routesByAgency == null)
      _routesByAgency = mapToValueList(getAllRoutes(), "agency", Agency.class);
    return list(_routesByAgency.get(agency));
  }
  
  @Override
  public List getStopsForStation(Stop station) {
  	if (_stopsByStation == null) {
      _stopsByStation = new HashMap>();
      for (Stop stop : getAllStops()) {
        if (stop.getLocationType() == 0 && stop.getParentStation() != null) {
          Stop parentStation = getStopForId(new AgencyAndId(
              stop.getId().getAgencyId(), stop.getParentStation()));
          List subStops = _stopsByStation.get(parentStation); 
          if (subStops == null) {
            subStops = new ArrayList(2);
            _stopsByStation.put(parentStation, subStops);
          }
          subStops.add(stop);
        }
      }
  	}
  	return list(_stopsByStation.get(station));
  }

  @Override
  public List getAllShapeIds() {
    ensureShapePointRelation();
    return new ArrayList(_shapePointsByShapeId.keySet());
  }

  @Override
  public List getShapePointsForShapeId(AgencyAndId shapeId) {
    ensureShapePointRelation();
    return list(_shapePointsByShapeId.get(shapeId));
  }

  @Override
  public List getStopTimesForTrip(Trip trip) {

    if (_stopTimesByTrip == null) {
      _stopTimesByTrip = mapToValueList(getAllStopTimes(), "trip", Trip.class);
      for (List stopTimes : _stopTimesByTrip.values())
        Collections.sort(stopTimes);
    }

    return list(_stopTimesByTrip.get(trip));
  }

  @Override
  public List getStopTimesForStop(Stop stop) {
    if (_stopTimesByStop == null)
      _stopTimesByStop = mapToValueList(getAllStopTimes(), "stop", Stop.class);
    return list(_stopTimesByStop.get(stop));
  }

  @Override
  public List getTripsForRoute(Route route) {
    if (_tripsByRoute == null)
      _tripsByRoute = mapToValueList(getAllTrips(), "route", Route.class);
    return list(_tripsByRoute.get(route));
  }

  @Override
  public List getTripsForBlockId(AgencyAndId blockId) {

    if (_tripsByBlockId == null) {
      _tripsByBlockId = new HashMap>();
      for (Trip trip : getAllTrips()) {
        if (trip.getBlockId() != null) {
          AgencyAndId bid = new AgencyAndId(trip.getId().getAgencyId(),
              trip.getBlockId());
          List trips = _tripsByBlockId.get(bid);
          if (trips == null) {
            trips = new ArrayList();
            _tripsByBlockId.put(bid, trips);
          }
          trips.add(trip);
        }
      }
    }

    return list(_tripsByBlockId.get(blockId));
  }

  @Override
  public List getFrequenciesForTrip(Trip trip) {
    if (_frequenciesByTrip == null)
      _frequenciesByTrip = mapToValueList(getAllFrequencies(), "trip",
          Trip.class);
    return list(_frequenciesByTrip.get(trip));
  }

  @Override
  public List getCalendarDatesForServiceId(
      AgencyAndId serviceId) {
    if (_calendarDatesByServiceId == null)
      _calendarDatesByServiceId = mapToValueList(getAllCalendarDates(),
          "serviceId", AgencyAndId.class);
    return list(_calendarDatesByServiceId.get(serviceId));
  }

  @Override
  public ServiceCalendar getCalendarForServiceId(AgencyAndId serviceId) {
    if (_calendarsByServiceId == null)
      _calendarsByServiceId = mapToValueList(getAllCalendars(), "serviceId",
          AgencyAndId.class);
    List calendars = list(_calendarsByServiceId.get(serviceId));
    switch (calendars.size()) {
      case 0:
        return null;
      case 1:
        return calendars.get(0);
    }
    throw new MultipleCalendarsForServiceIdException(serviceId);
  }

  /****
   * Private Methods
   ****/
  
  private void ensureShapePointRelation() {
    if (_shapePointsByShapeId == null) {
      _shapePointsByShapeId = mapToValueList(getAllShapePoints(), "shapeId",
          AgencyAndId.class);
      for (List shapePoints : _shapePointsByShapeId.values())
        Collections.sort(shapePoints);
    }
  }

  private static  List list(List list) {
    if (list == null)
      list = new ArrayList();
    return Collections.unmodifiableList(list);
  }

  @SuppressWarnings("unchecked")
  private static  Map> mapToValueList(Iterable values,
      String property, Class keyType) {
    return mapToValueCollection(values, property, keyType,
        new ArrayList().getClass());
  }

  @SuppressWarnings("unchecked")
  private static , CIMPL extends C> Map mapToValueCollection(
      Iterable values, String property, Class keyType,
      Class collectionType) {

    Map byKey = new HashMap();
    SimplePropertyQuery query = new SimplePropertyQuery(property);

    for (V value : values) {

      K key = (K) query.invoke(value);
      C valuesForKey = byKey.get(key);
      if (valuesForKey == null) {

        try {
          valuesForKey = collectionType.newInstance();
        } catch (Exception ex) {
          throw new EntityInstantiationException(collectionType, ex);
        }

        byKey.put(key, valuesForKey);
      }
      valuesForKey.add(value);
    }

    return byKey;
  }

  private  Map clearMap(Map map) {
    if (map != null)
      map.clear();
    return null;
  }

  private static final class SimplePropertyQuery {

    private String[] _properties;

    public SimplePropertyQuery(String query) {
      _properties = query.split("\\.");
    }

    public Object invoke(Object value) {
      for (String property : _properties) {
        BeanWrapper wrapper = BeanWrapperFactory.wrap(value);
        value = wrapper.getPropertyValue(property);
      }
      return value;
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy