/* This program is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package org.opentripplanner.routing.alertpatch;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.onebusaway.gtfs.model.Agency;
import org.onebusaway.gtfs.model.AgencyAndId;
import org.onebusaway.gtfs.model.Route;
import org.onebusaway.gtfs.model.Stop;
import org.onebusaway.gtfs.model.Trip;
import org.opentripplanner.api.adapters.AgencyAndIdAdapter;
import org.opentripplanner.routing.core.State;
import org.opentripplanner.routing.edgetype.PreAlightEdge;
import org.opentripplanner.routing.edgetype.PreBoardEdge;
import org.opentripplanner.routing.edgetype.TripPattern;
import org.opentripplanner.routing.graph.Edge;
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.routing.vertextype.TransitStop;
/**
* This adds a note to all boardings of a given route or stop (optionally, in a given direction)
*
* @author novalis
*
*/
@XmlRootElement(name = "AlertPatch")
public class AlertPatch implements Serializable {
private static final long serialVersionUID = 20140319L;
private String id;
private Alert alert;
private List<TimePeriod> timePeriods = new ArrayList<TimePeriod>();
private String agency;
private AgencyAndId route;
private AgencyAndId trip;
private AgencyAndId stop;
private String direction;
@XmlElement
public Alert getAlert() {
return alert;
}
public boolean displayDuring(State state) {
for (TimePeriod timePeriod : timePeriods) {
if (state.getTimeSeconds() >= timePeriod.startTime) {
if (state.getStartTimeSeconds() < timePeriod.endTime) {
return true;
}
}
}
return false;
}
@XmlElement
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void apply(Graph graph) {
Agency agency = this.agency != null ? graph.index.agencyForId.get(this.agency) : null;
Route route = this.route != null ? graph.index.routeForId.get(this.route) : null;
Stop stop = this.stop != null ? graph.index.stopForId.get(this.stop) : null;
Trip trip = this.trip != null ? graph.index.tripForId.get(this.trip) : null;
if (route != null || trip != null || agency != null) {
Collection<TripPattern> tripPatterns;
if(trip != null) {
tripPatterns = new LinkedList<TripPattern>();
TripPattern tripPattern = graph.index.patternForTrip.get(trip);
if(tripPattern != null) {
tripPatterns.add(tripPattern);
}
} else if (route != null) {
tripPatterns = graph.index.patternsForRoute.get(route);
} else {
tripPatterns = graph.index.patternsForAgency.get(agency);
}
for (TripPattern tripPattern : tripPatterns) {
if (direction != null && ! direction.equals(tripPattern.getDirection())) {
continue;
}
for (int i = 0; i < tripPattern.stopPattern.stops.length; i++) {
if (stop == null || stop.equals(tripPattern.stopPattern.stops[i])) {
graph.addAlertPatch(tripPattern.boardEdges[i], this);
graph.addAlertPatch(tripPattern.alightEdges[i], this);
}
}
}
} else if (stop != null) {
TransitStop transitStop = graph.index.stopVertexForStop.get(stop);
for (Edge edge : transitStop.getOutgoing()) {
if (edge instanceof PreBoardEdge) {
graph.addAlertPatch(edge, this);
break;
}
}
for (Edge edge : transitStop.getIncoming()) {
if (edge instanceof PreAlightEdge) {
graph.addAlertPatch(edge, this);
break;
}
}
}
}
public void remove(Graph graph) {
Agency agency = this.agency != null ? graph.index.agencyForId.get(this.agency) : null;
Route route = this.route != null ? graph.index.routeForId.get(this.route) : null;
Stop stop = this.stop != null ? graph.index.stopForId.get(this.stop) : null;
Trip trip = this.trip != null ? graph.index.tripForId.get(this.trip) : null;
if (route != null || trip != null || agency != null) {
Collection<TripPattern> tripPatterns;
if(trip != null) {
tripPatterns = new LinkedList<TripPattern>();
TripPattern tripPattern = graph.index.patternForTrip.get(trip);
if(tripPattern != null) {
tripPatterns.add(tripPattern);
}
} else if (route != null) {
tripPatterns = graph.index.patternsForRoute.get(route);
} else {
tripPatterns = graph.index.patternsForAgency.get(agency);
}
for (TripPattern tripPattern : tripPatterns) {
if (direction != null && ! direction.equals(tripPattern.getDirection())) {
continue;
}
for (int i = 0; i < tripPattern.stopPattern.stops.length; i++) {
if (stop == null || stop.equals(tripPattern.stopPattern.stops[i])) {
graph.removeAlertPatch(tripPattern.boardEdges[i], this);
graph.removeAlertPatch(tripPattern.alightEdges[i], this);
}
}
}
} else if (stop != null) {
TransitStop transitStop = graph.index.stopVertexForStop.get(stop);
for (Edge edge : transitStop.getOutgoing()) {
if (edge instanceof PreBoardEdge) {
graph.removeAlertPatch(edge, this);
break;
}
}
for (Edge edge : transitStop.getIncoming()) {
if (edge instanceof PreAlightEdge) {
graph.removeAlertPatch(edge, this);
break;
}
}
}
}
public void setAlert(Alert alert) {
this.alert = alert;
}
private void writeObject(ObjectOutputStream os) throws IOException {
if (timePeriods instanceof ArrayList<?>) {
((ArrayList<TimePeriod>) timePeriods).trimToSize();
}
os.defaultWriteObject();
}
public void setTimePeriods(List<TimePeriod> periods) {
timePeriods = periods;
}
public String getAgency() {
return agency;
}
@XmlJavaTypeAdapter(AgencyAndIdAdapter.class)
public AgencyAndId getRoute() {
return route;
}
@XmlJavaTypeAdapter(AgencyAndIdAdapter.class)
public AgencyAndId getTrip() {
return trip;
}
@XmlJavaTypeAdapter(AgencyAndIdAdapter.class)
public AgencyAndId getStop() {
return stop;
}
public void setAgencyId(String agency) {
this.agency = agency;
}
public void setRoute(AgencyAndId route) {
this.route = route;
}
public void setTrip(AgencyAndId trip) {
this.trip = trip;
}
public void setDirection(String direction) {
if (direction != null && direction.equals("")) {
direction = null;
}
this.direction = direction;
}
@XmlElement
public String getDirection() {
return direction;
}
public void setStop(AgencyAndId stop) {
this.stop = stop;
}
public boolean equals(Object o) {
if (!(o instanceof AlertPatch)) {
return false;
}
AlertPatch other = (AlertPatch) o;
if (direction == null) {
if (other.direction != null) {
return false;
}
} else {
if (!direction.equals(other.direction)) {
return false;
}
}
if (agency == null) {
if (other.agency != null) {
return false;
}
} else {
if (!agency.equals(other.agency)) {
return false;
}
}
if (trip == null) {
if (other.trip != null) {
return false;
}
} else {
if (!trip.equals(other.trip)) {
return false;
}
}
if (stop == null) {
if (other.stop != null) {
return false;
}
} else {
if (!stop.equals(other.stop)) {
return false;
}
}
if (route == null) {
if (other.route != null) {
return false;
}
} else {
if (!route.equals(other.route)) {
return false;
}
}
if (alert == null) {
if (other.alert != null) {
return false;
}
} else {
if (!alert.equals(other.alert)) {
return false;
}
}
if (id == null) {
if (other.id != null) {
return false;
}
} else {
if (!id.equals(other.id)) {
return false;
}
}
if (timePeriods == null) {
if (other.timePeriods != null) {
return false;
}
} else {
if (!timePeriods.equals(other.timePeriods)) {
return false;
}
}
return true;
}
public int hashCode() {
return ((direction == null ? 0 : direction.hashCode()) +
(agency == null ? 0 : agency.hashCode()) +
(trip == null ? 0 : trip.hashCode()) +
(stop == null ? 0 : stop.hashCode()) +
(route == null ? 0 : route.hashCode()) +
(alert == null ? 0 : alert.hashCode()));
}
}