Java tutorial
/* * Copyright (C) 2014 Kurt Raschke <kurt@kurtraschke.com> * * 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 com.kurtraschke.wmata.gtfsrealtime.services; import org.onebusaway.gtfs.model.AgencyAndId; import org.onebusaway.gtfs.model.Route; import org.onebusaway.gtfs.services.GtfsRelationalDao; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.kurtraschke.wmata.gtfsrealtime.WMATAAPIException; import com.kurtraschke.wmata.gtfsrealtime.api.routes.WMATARoute; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; /** * * @author kurt */ @Singleton public class WMATARouteMapperService { private static final Logger _log = LoggerFactory.getLogger(WMATARouteMapperService.class); private WMATAAPIService _api; private GtfsRelationalDao _dao; private String[] _badRoutes; private String _agencyId; private Properties _staticMappings; private final Pattern _routeExtract = Pattern.compile("^([A-Z0-9]+)(c?v?S?[0-9]?).*$"); private Map<String, AgencyAndId> _routeMappings = new HashMap<String, AgencyAndId>(); private Predicate<String> _matchBadRoutes; private List<Route> _gtfsRoutes; @Inject public void setWMATAAPIService(WMATAAPIService api) { _api = api; } @Inject public void setGtfsRelationalDao(GtfsRelationalDao dao) { _dao = dao; } @Inject public void setBadRoutes(@Named("WMATA.badRoutes") String badRoutesString) { _badRoutes = badRoutesString.split(","); _matchBadRoutes = Predicates.in(Arrays.asList(_badRoutes)); } @Inject public void setAgencyId(@Named("WMATA.agencyID") String agencyId) { _agencyId = agencyId; } @Inject public void setStaticMappings(@Named("WMATA.staticMappings") Properties staticMappings) { _staticMappings = staticMappings; } @PostConstruct public void start() throws WMATAAPIException { _gtfsRoutes = _dao.getRoutesForAgency(_dao.getAgencyForId(_agencyId)); primeCaches(); } public void primeCaches() throws WMATAAPIException { for (WMATARoute r : _api.downloadRouteList().getRoutes()) { AgencyAndId mapResult = mapBusRoute(r.getRouteID()); if (mapResult != null) { _routeMappings.put(r.getRouteID(), mapResult); } } String[] railRoutes = new String[] { "RED", "ORANGE", "YELLOW", "GREEN", "BLUE", "SILVER" }; //FIXME: avoid hardcoding for (String r : railRoutes) { AgencyAndId mapResult = mapRailRoute(r); if (mapResult != null) { _routeMappings.put(r, mapResult); } } } private AgencyAndId mapBusRoute(String routeID) { if (_staticMappings.containsKey(routeID)) { String staticMappedRoute = _staticMappings.getProperty(routeID); Optional<Route> matchedRoute = Iterables.tryFind(_gtfsRoutes, new ShortNameFilterPredicate(staticMappedRoute, true)); if (matchedRoute.isPresent()) { AgencyAndId mappedRouteID = matchedRoute.get().getId(); _log.info( "Mapped WMATA route " + routeID + " to GTFS route " + mappedRouteID + " (using override)"); return mappedRouteID; } else { _log.warn("Could not apply static mapping of {} to {}; continuing...", routeID, staticMappedRoute); } } Matcher m = _routeExtract.matcher(routeID); if (m.matches()) { final String filteredRouteID = m.group(1); if (!_matchBadRoutes.apply(filteredRouteID)) { Optional<Route> matchedRoute = Iterables.tryFind(_gtfsRoutes, new ShortNameFilterPredicate(filteredRouteID, true)); if (matchedRoute.isPresent()) { AgencyAndId mappedRouteID = matchedRoute.get().getId(); _log.info("Mapped WMATA route " + routeID + " to GTFS route " + mappedRouteID); return mappedRouteID; } else { _log.warn("Could not map WMATA route: " + routeID); return null; } } else { _log.warn("Not mapping blacklisted WMATA route: " + routeID); return null; } } else { _log.warn("Not mapping malformed WMATA route: " + routeID); return null; } } private AgencyAndId mapRailRoute(String routeName) { Optional<Route> matchedRoute = Iterables.tryFind(_gtfsRoutes, new ShortNameFilterPredicate(routeName, false)); if (matchedRoute.isPresent()) { AgencyAndId mappedRouteID = matchedRoute.get().getId(); _log.info("Mapped WMATA route " + routeName + " to GTFS route " + mappedRouteID); return mappedRouteID; } else { _log.warn("Could not map WMATA route: " + routeName); return null; } } public AgencyAndId getRouteMapping(String routeID) { if (_routeMappings.containsKey(routeID)) { return _routeMappings.get(routeID); } else { return null; } } public Map<String, AgencyAndId> getRouteMappings() { return ImmutableMap.<String, AgencyAndId>copyOf(_routeMappings); } private static class ShortNameFilterPredicate implements Predicate<Route> { private String shortName; private boolean caseSensitive; public ShortNameFilterPredicate(String shortName, boolean caseSensitive) { this.shortName = shortName; this.caseSensitive = caseSensitive; } @Override public boolean apply(Route r) { if (r.getShortName() != null) { if (caseSensitive) { return r.getShortName().equals(shortName); } else { return r.getShortName().equalsIgnoreCase(shortName); } } else { return false; } } } }