View Javadoc
1   package org.djutils.data;
2   
3   import java.lang.reflect.InvocationTargetException;
4   import java.lang.reflect.Method;
5   import java.util.Objects;
6   
7   import org.djunits.value.Value;
8   import org.djunits.value.base.Scalar;
9   import org.djutils.base.Identifiable;
10  import org.djutils.exceptions.Throw;
11  import org.djutils.primitives.Primitive;
12  
13  /**
14   * Column identifier and descriptor.
15   * <p>
16   * Copyright (c) 2020-2025 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
17   * BSD-style license. See <a href="https://djutils.org/docs/current/djutils/licenses.html">DJUTILS License</a>.
18   * </p>
19   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
20   * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
21   * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
22   * @param <T> value type
23   */
24  public class Column<T> implements Identifiable
25  {
26      /** Id. */
27      private final String id;
28  
29      /** Description. */
30      private final String description;
31  
32      /** Value type. */
33      private final Class<T> valueType;
34  
35      /** Unit. */
36      private final String unit;
37  
38      /**
39       * Make a new column for a table with an id, description, type, and unit.
40       * @param id id of the column
41       * @param description description of the column
42       * @param valueType value type of the column
43       * @param unit unit, may be {@code null}
44       */
45      @SuppressWarnings("unchecked")
46      public Column(final String id, final String description, final Class<T> valueType, final String unit)
47      {
48          Throw.whenNull(id, "id may not be null.");
49          Throw.when(id.length() == 0, IllegalArgumentException.class, "id cannot be empty");
50          Throw.whenNull(description, "description may not be null.");
51          Throw.whenNull(valueType, "valueType may not be null.");
52          this.id = id;
53          this.description = description;
54          this.valueType = valueType.isPrimitive() ? (Class<T>) Primitive.getWrapper(valueType) : valueType;
55          Throw.when(Value.class.isAssignableFrom(valueType) && (unit == null || unit.length() == 0),
56                  IllegalArgumentException.class, "For a DJUNITS value, unit cannot be null or the empty string");
57          if (Scalar.class.isAssignableFrom(valueType))
58          {
59              try
60              {
61                  Method valueOfMethod = valueType.getDeclaredMethod("valueOf", String.class);
62                  valueOfMethod.invoke(null, "1.0" + unit);
63              }
64              catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
65                      | SecurityException exception)
66              {
67                  throw new IllegalArgumentException(
68                          "unit of the Column does not belong to Scalar of type " + valueType.getSimpleName());
69              }
70          }
71          this.unit = unit;
72      }
73  
74      /**
75       * Make a new column for a table with an id, description, type. The unit is blank (null).
76       * @param id id of the column
77       * @param description description of the column
78       * @param valueType value type of the column
79       */
80      public Column(final String id, final String description, final Class<T> valueType)
81      {
82          this(id, description, valueType, null);
83      }
84  
85      @Override
86      public String getId()
87      {
88          return this.id;
89      }
90  
91      /**
92       * Returns the column description.
93       * @return column description
94       */
95      public String getDescription()
96      {
97          return this.description;
98      }
99  
100     /**
101      * Returns the type of the values in the column.
102      * @return type of the values in the column
103      */
104     public Class<T> getValueType()
105     {
106         return this.valueType;
107     }
108 
109     /**
110      * Returns the unit of the column. Data is written an read using this unit.
111      * @return unit of the column
112      */
113     public String getUnit()
114     {
115         return this.unit;
116     }
117 
118     @Override
119     public int hashCode()
120     {
121         return Objects.hash(this.id);
122     }
123 
124     @Override
125     public boolean equals(final Object obj)
126     {
127         if (this == obj)
128         {
129             return true;
130         }
131         if (obj == null)
132         {
133             return false;
134         }
135         if (getClass() != obj.getClass())
136         {
137             return false;
138         }
139         Column<?> other = (Column<?>) obj;
140         return Objects.equals(this.id, other.id);
141     }
142 
143     @Override
144     public String toString()
145     {
146         return "Column [id=" + this.id + ", description=" + this.description + ", valueType=" + this.valueType
147                 + (this.unit == null ? "]" : ", unit=" + this.unit + "]");
148     }
149 
150 }