View Javadoc
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-2019 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 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&lt;?&gt;; 1st class
50       * @param classes Class&lt;?&gt;...; 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&lt;?&gt;; 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 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 }