View Javadoc
1   package org.djutils.data.serialization;
2   
3   import java.lang.reflect.InvocationTargetException;
4   import java.lang.reflect.Method;
5   import java.util.LinkedHashMap;
6   import java.util.Map;
7   
8   import org.djunits.unit.Unit;
9   import org.djunits.value.vfloat.scalar.base.FloatScalar;
10  
11  /**
12   * FloatScalarSerializer (de)serializes DJUNITS float scalars. This class extends DoubleScalarSerializer. Since the target class
13   * to deserialize is given to the deserialize method, the DoubleScalarSerializer.deserialize can also deserialize FloatScalar
14   * values.
15   * <p>
16   * Copyright (c) 2020-2024 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 <U> the unit type
23   * @param <S> the scalar type
24   */
25  public class FloatScalarSerializer<U extends Unit<U>, S extends FloatScalar<U, S>> implements TextSerializer<S>
26  {
27      /** cache of the retrieved valueOf(String) methods for scalars based on the stored string. */
28      private static Map<String, Method> valueOfMethodCache = new LinkedHashMap<>();
29  
30      /** cache of the retrieved unit instances based on the unit string. */
31      private static Map<String, Unit<?>> unitCache = new LinkedHashMap<>();
32  
33      /**
34       * Serialize an Scalar value to text in such a way that it can be deserialized with the corresponding deserializer.
35       * @param value Object; the scalar to serialize
36       * @return String; a string representation of the value that can later be deserialized
37       */
38      @SuppressWarnings("unchecked")
39      @Override
40      public String serialize(final S value, final String unitString)
41      {
42          if (value == null)
43          {
44              return null;
45          }
46  
47          String key = value.getClass().getSimpleName() + "_" + unitString;
48          Unit<?> unit = unitCache.get(key);
49          if (unit == null)
50          {
51              unit = value.getDisplayUnit().getQuantity().of(unitString);
52              unitCache.put(key, unit);
53          }
54          return String.valueOf(value.getInUnit((U) unit));
55      }
56  
57      /**
58       * Deserialize a String to the correct Scalar value. The method caches the valueOf(String) method for repeated use.
59       * @param text String; the text to deserialize
60       * @return S; the reconstructed scalar
61       */
62      @SuppressWarnings("unchecked")
63      @Override
64      public S deserialize(final Class<S> type, final String text, final String unit)
65      {
66          if (text == null || text.isEmpty())
67          {
68              return null;
69          }
70          try
71          {
72              Method valueOfMethod = valueOfMethodCache.get(type.getName());
73              if (valueOfMethod == null)
74              {
75                  valueOfMethod = type.getDeclaredMethod("valueOf", String.class);
76                  valueOfMethodCache.put(type.getName(), valueOfMethod);
77              }
78              return (S) valueOfMethod.invoke(null, text + unit);
79          }
80          catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
81                  | SecurityException exception)
82          {
83              throw new RuntimeException(exception);
84          }
85      }
86  
87  }