1 package org.opentrafficsim.road.gtu.strategical.od;
2
3 import java.io.Serializable;
4 import java.util.ArrayList;
5 import java.util.List;
6
7 import org.djutils.exceptions.Throw;
8 import org.opentrafficsim.base.Identifiable;
9
10 /**
11 * A categorization determines for what part of traffic certain demand data is applicable. By default, this is always for a
12 * given origin-destination pair and time period. A categorization adds to this additional segregation. For example, per lane,
13 * per vehicle class, etc.
14 * <p>
15 * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
16 * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
17 * <p>
18 * @version $Revision$, $LastChangedDate$, by $Author$, initial version Sep 15, 2016 <br>
19 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
20 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
21 * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
22 */
23 public class Categorization implements Serializable, Identifiable
24 {
25
26 /** Empty categorization. */
27 public static final Categorizational/od/Categorization.html#Categorization">Categorization UNCATEGORIZED = new Categorization("Uncategorized");
28
29 /** */
30 private static final long serialVersionUID = 20160921L;
31
32 /** Id. */
33 private final String id;
34
35 /** Set of categorization classes. */
36 private final List<Class<?>> classes = new ArrayList<>();
37
38 /**
39 * @param id String; id
40 */
41 private Categorization(final String id)
42 {
43 Throw.whenNull(id, "Id may not be null.");
44 this.id = id;
45 }
46
47 /**
48 * @param id String; Id
49 * @param class1 Class<?>; 1st class
50 * @param classes Class<?>...; other classes
51 * @throws IllegalArgumentException if any class is given multiple times
52 * @throws NullPointerException if any input is null
53 */
54 public Categorization(final String id, final Class<?> class1, final Class<?>... classes)
55 {
56 this(id);
57 Throw.whenNull(class1, "Classes may not be null.");
58 this.classes.add(class1);
59 for (Class<?> clazz : classes)
60 {
61 Throw.whenNull(clazz, "Classes may not be null.");
62 Throw.when(this.classes.contains(clazz), IllegalArgumentException.class, "Class %s is given multiple times.",
63 clazz);
64 this.classes.add(clazz);
65 }
66 }
67
68 /**
69 * Returns the number of category classes defined.
70 * @return number of category classes defined
71 */
72 public final int size()
73 {
74 return this.classes.size();
75 }
76
77 /**
78 * Returns the i'th class.
79 * @param i int; index of the class
80 * @return the i'th class
81 * @throws IndexOutOfBoundsException if index i is out of bounds
82 */
83 public final Class<?> get(final int i)
84 {
85 Throw.when(i < 0 || i >= size(), IndexOutOfBoundsException.class,
86 "Index %d is out of range for categorization of size %d.", i, size());
87 return this.classes.get(i);
88 }
89
90 /**
91 * @return id.
92 */
93 @Override
94 public final String getId()
95 {
96 return this.id;
97 }
98
99 /**
100 * Returns whether the categorization contains a class that is, or is a sub type of, the given class.
101 * @param clazz Class<?>; class to check
102 * @return whether the categorization contains a class that is, or is a sub type of, the given class
103 */
104 public final boolean entails(final Class<?> clazz)
105 {
106 for (Class<?> clazz2 : this.classes)
107 {
108 if (clazz.isAssignableFrom(clazz2))
109 {
110 return true;
111 }
112 }
113 return false;
114 }
115
116 /** {@inheritDoc} */
117 @Override
118 public final int hashCode()
119 {
120 final int prime = 31;
121 int result = 1;
122 result = prime * result + ((this.classes == null) ? 0 : this.classes.hashCode());
123 return result;
124 }
125
126 /** {@inheritDoc} */
127 @Override
128 public final boolean equals(final Object obj)
129 {
130 if (this == obj)
131 {
132 return true;
133 }
134 if (obj == null)
135 {
136 return false;
137 }
138 if (getClass() != obj.getClass())
139 {
140 return false;
141 }
142 Categorization./../../../org/opentrafficsim/road/gtu/strategical/od/Categorization.html#Categorization">Categorization other = (Categorization) obj;
143 if (this.classes == null)
144 {
145 if (other.classes != null)
146 {
147 return false;
148 }
149 }
150 else if (!this.classes.equals(other.classes))
151 {
152 return false;
153 }
154 return true;
155 }
156
157 /** {@inheritDoc} */
158 @Override
159 public final String toString()
160 {
161 return "Categorization [id=" + this.id + ", classes=" + this.classes + "]";
162 }
163
164 }