Package org.onebusaway.federations.impl

Source Code of org.onebusaway.federations.impl.FederatedServiceCollectionImpl$ProviderCollector

/**
* Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org>
*
* 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.federations.impl;

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.exceptions.MultipleServiceAreasServiceException;
import org.onebusaway.exceptions.NoSuchAgencyServiceException;
import org.onebusaway.exceptions.OutOfServiceAreaServiceException;
import org.onebusaway.exceptions.ServiceAreaServiceException;
import org.onebusaway.federations.FederatedService;
import org.onebusaway.federations.FederatedServiceCollection;
import org.onebusaway.geospatial.model.CoordinateBounds;
import org.onebusaway.geospatial.model.CoordinatePoint;

import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.index.ItemVisitor;
import com.vividsolutions.jts.index.strtree.STRtree;

/**
* A basic {@link FederatedServiceCollection} implementation that provides
* methods for query a set of {@link FederatedService} instances. See the static
* factory method {@link #create(List, Class)} for a convenient way of
* constructing a {@link FederatedServiceCollectionImpl} from a set of
* {@link FederatedService} instances of a particular type.
*
* @author bdferris
* @see FederatedService
* @see FederatedServiceCollection
*/
public class FederatedServiceCollectionImpl implements
    FederatedServiceCollection {

  private Set<FederatedService> _services;

  private Map<String, FederatedService> _servicesByAgencyId = new HashMap<String, FederatedService>();

  private STRtree _tree;

  public static <T extends FederatedService> FederatedServiceCollectionImpl create(
      List<T> serviceProviders, Class<T> serviceInterface) {
    Map<FederatedService, Map<String, List<CoordinateBounds>>> map = FederatedServiceLibrary.getFederatedServiceAgencyCoverage(
        serviceProviders, serviceInterface);
    return new FederatedServiceCollectionImpl(map);
  }

  public FederatedServiceCollectionImpl(
      Map<FederatedService, Map<String, List<CoordinateBounds>>> services) {

    _services = Collections.unmodifiableSet(services.keySet());

    _tree = new STRtree();

    for (Map.Entry<FederatedService, Map<String, List<CoordinateBounds>>> entry : services.entrySet()) {
      FederatedService service = entry.getKey();
      Map<String, List<CoordinateBounds>> agencyIdsAndCoverage = entry.getValue();
      for (Map.Entry<String, List<CoordinateBounds>> acEntry : agencyIdsAndCoverage.entrySet()) {

        String agencyId = acEntry.getKey();
        List<CoordinateBounds> coverage = acEntry.getValue();

        _servicesByAgencyId.put(agencyId, service);

        for (CoordinateBounds rc : coverage) {
          Envelope env = new Envelope(rc.getMinLon(), rc.getMaxLon(),
              rc.getMinLat(), rc.getMaxLat());
          _tree.insert(env, service);
        }
      }
    }

    _tree.build();
  }

  public FederatedServiceCollectionImpl() {
    this(new HashMap<FederatedService, Map<String, List<CoordinateBounds>>>());
  }

  /****
   * {@link FederatedServiceCollection} Interface
   ****/

  @Override
  public Set<FederatedService> getAllServices() {
    return _services;
  }

  @Override
  public FederatedService getServiceForAgencyId(String agencyId)
      throws ServiceAreaServiceException {
    FederatedService provider = _servicesByAgencyId.get(agencyId);
    if (provider == null)
      throw new NoSuchAgencyServiceException(agencyId);
    return provider;
  }

  @Override
  public FederatedService getServiceForAgencyIds(Iterable<String> agencyIds)
      throws ServiceAreaServiceException {
    Set<FederatedService> providers = new HashSet<FederatedService>();
    for (String id : agencyIds) {
      FederatedService provider = getServiceForAgencyId(id);
      if (provider == null)
        throw new NoSuchAgencyServiceException(id);
      providers.add(provider);
    }
    return getProviderFromProviders(providers);
  }

  @Override
  public FederatedService getServiceForBounds(CoordinateBounds bounds)
      throws ServiceAreaServiceException {
    return getServiceForBounds(bounds.getMinLat(), bounds.getMinLon(),
        bounds.getMaxLat(), bounds.getMaxLon());
  }

  @Override
  public FederatedService getServiceForBounds(double lat1, double lon1,
      double lat2, double lon2) throws ServiceAreaServiceException {
    Envelope rectangle = new Envelope(lon1, lon2, lat1, lat2);
    return getProviderForRectangle(rectangle);
  }

  @Override
  public FederatedService getServiceForLocation(double lat, double lon)
      throws ServiceAreaServiceException {
    return getServiceForBounds(lat, lon, lat, lon);
  }

  @Override
  public FederatedService getServiceForLocations(List<CoordinatePoint> points)
      throws ServiceAreaServiceException {

    FederatedService service = null;

    for (CoordinatePoint point : points) {

      FederatedService provider = getServiceForLocation(point.getLat(),
          point.getLon());

      if (service == null) {
        service = provider;
      } else if (service != provider) {
        throw new MultipleServiceAreasServiceException();
      }
    }

    if (service == null)
      throw new OutOfServiceAreaServiceException();

    return service;
  }

  /****
   * Private Methods
   ****/

  private FederatedService getProviderForRectangle(Envelope env)
      throws ServiceAreaServiceException {
    ProviderCollector collector = new ProviderCollector();
    if (_tree.size() != 0)
      _tree.query(env, collector);
    Set<FederatedService> providers = collector.getProviders();
    return getProviderFromProviders(providers);
  }

  private FederatedService getProviderFromProviders(
      Set<FederatedService> providers) throws OutOfServiceAreaServiceException,
      MultipleServiceAreasServiceException {
    if (providers.size() == 1)
      return providers.iterator().next();
    if (providers.size() == 0)
      throw new OutOfServiceAreaServiceException();
    throw new MultipleServiceAreasServiceException();
  }

  private class ProviderCollector implements ItemVisitor {

    private Set<FederatedService> _providers = new HashSet<FederatedService>();

    public Set<FederatedService> getProviders() {
      return _providers;
    }

    @Override
    public void visitItem(Object item) {
      _providers.add((FederatedService) item);
    }
  }
}
TOP

Related Classes of org.onebusaway.federations.impl.FederatedServiceCollectionImpl$ProviderCollector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.