MATSIM
AbstractRoute.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * AbstractRoute.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2008 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 
21 package org.matsim.core.population.routes;
22 
23 import org.matsim.api.core.v01.Id;
27 
33 public abstract class AbstractRoute implements Route, Cloneable {
34  // This has a public non-final non-empty method, which is "clone". But in the end this is how it is designed.
35  // So we leave it as is; if we ever want to re-design it in the core, we will have to copy it and start
36  // from the copy. kai, may'17
37 
38  protected static final double UNDEFINED_TIME = Double.NEGATIVE_INFINITY;
39 
40  private boolean locked = false ;
41 
42  private double dist = Double.NaN;
43 
44  protected double travTime = UNDEFINED_TIME;
45 
46  private Id<Link> startLinkId = null;
47  private Id<Link> endLinkId = null;
48 
49  public AbstractRoute(final Id<Link> startLinkId, final Id<Link> endLinkId) {
50  this.startLinkId = startLinkId;
51  this.endLinkId = endLinkId;
52  }
53 
54  protected static OptionalTime asOptionalTime(double seconds) {
55  return seconds == UNDEFINED_TIME ? OptionalTime.undefined() : OptionalTime.defined(seconds);
56  }
57 
58  @Override
59  public final double getDistance() {
60  return dist;
61  }
62 
63  @Override
64  public final void setDistance(final double dist) {
65  this.dist = dist;
66  }
67 
68  @Override
69  public final OptionalTime getTravelTime() {
70  return asOptionalTime(this.travTime);
71  }
72 
73  @Override
74  public final void setTravelTime(final double travTime) {
75  OptionalTime.assertDefined(travTime);
76  this.travTime = travTime;
77  }
78 
79  @Override
80  public void setTravelTimeUndefined() {
81  this.travTime = UNDEFINED_TIME;
82  }
83 
84  @Override
85  public final void setEndLinkId(final Id<Link> linkId) {
86  testForLocked();
87  this.endLinkId = linkId;
88  }
89 
90  @Override
91  public final void setStartLinkId(final Id<Link> linkId) {
92  testForLocked();
93  this.startLinkId = linkId;
94  }
95 
96  @Override
97  public final Id<Link> getStartLinkId() {
98  return this.startLinkId;
99  }
100 
101  @Override
102  public final Id<Link> getEndLinkId() {
103  return this.endLinkId;
104  }
105 
106  public final void setLocked() {
107  locked = true ;
108  }
109 
110  @Override
111  public AbstractRoute clone() {
112  // "clone" is some automagic that, by itself, makes a copy of the "bit pattern" of the object. That is:
113  // * the content of primitive types is copied
114  // * for objects the reference to the objects is copied.
115  // Consequences for matsim:
116  // * primitive types can be changed on the copy without affecting the original
117  // * the references to objects can be changed on the copy without affecting the original. For example, a copy can
118  // point to other links or nodes or persons or IDs.
119  // * One has to be careful with objects where the contents can be changed AND they are not shared between the
120  // original and the copy. For example, changing the income of the person is not a problem since it is the same
121  // for two plans pointing to the same person. In contrast (and potentially quite dangerous): the contents of
122  // Customizable (currently not applicable for Route) would have to be explicitly deepcopied.
123  // The method can only be called if a class implements "Cloneable"; otherwise, it leads to a runtime exception (!).
124  // It is, however, sufficient to have clone available as protected.
125  try {
126  final AbstractRoute clone = (AbstractRoute) super.clone();
127  clone.locked = false ; // not obvious that this is the right way to go.
128  return clone;
129  } catch (CloneNotSupportedException e) {
130  throw new AssertionError(e);
131  }
132  }
133 
134  @Override
135  public String toString() {
136  String str = "";
137  str += " startLinkId=" + startLinkId ;
138  str += " endLinkId=" + endLinkId ;
139  str += " travTime=" + travTime;
140  str += " dist=" + dist ;
141  return str ;
142  }
143 
144  private void testForLocked() {
145  if ( locked ) {
146  throw new RuntimeException( "Route is locked; too late to do this. See comments in code.") ;
147  }
148  }
149 
150 }
final void setEndLinkId(final Id< Link > linkId)
final void setTravelTime(final double travTime)
final void setStartLinkId(final Id< Link > linkId)
static OptionalTime asOptionalTime(double seconds)
static OptionalTime defined(double seconds)
AbstractRoute(final Id< Link > startLinkId, final Id< Link > endLinkId)
static void assertDefined(double seconds)