View Javadoc
1   /*
2    * Copyright (C) 2021-2023 Dipl.-Inform. Kai Hofmann. All rights reserved!
3    */
4   package de.powerstat.validation.values;
5   
6   
7   import java.util.Objects;
8   
9   import de.powerstat.validation.interfaces.IValueObject;
10  
11  
12  /**
13   * Millisecond.
14   *
15   * Not DSGVO relevant.
16   *
17   * TODO Listener
18   * TODO min, max
19   */
20  public final class Millisecond implements Comparable<Millisecond>, IValueObject
21   {
22    /* *
23     * Cache for singletons.
24     */
25    // private static final Map<Integer, Millisecond> CACHE = new WeakHashMap<>();
26  
27    /**
28     * Overflow constant.
29     */
30    private static final String OVERFLOW = "Overflow"; //$NON-NLS-1$
31  
32    /**
33     * Underflow constant.
34     */
35    private static final String UNDERFLOW = "Underflow"; //$NON-NLS-1$
36  
37    /**
38     * Milliseond.
39     */
40    private final int millisecond;
41  
42  
43    /**
44     * Constructor.
45     *
46     * @param millisecond Millisecond 0-999
47     * @throws IndexOutOfBoundsException When the milliseond is less than 0 or greater than 999
48     */
49    private Millisecond(final int millisecond)
50     {
51      super();
52      if ((millisecond < 0) || (millisecond > 999))
53       {
54        throw new IndexOutOfBoundsException("Millisecond out of range (0-999)!"); //$NON-NLS-1$
55       }
56      this.millisecond = millisecond;
57     }
58  
59  
60    /**
61     * Millisecond factory.
62     *
63     * @param millisecond Millisecond 0-999
64     * @return Millisecond object
65     */
66    public static Millisecond of(final int millisecond)
67     {
68      /*
69      synchronized (Millisecond.class)
70       {
71        Millisecond obj = Millisecond.CACHE.get(millisecond);
72        if (obj != null)
73         {
74          return obj;
75         }
76        obj = new Millisecond(millisecond);
77        Millisecond.CACHE.put(Integer.valueOf(millisecond), obj);
78        return obj;
79       }
80      */
81      return new Millisecond(millisecond);
82     }
83  
84  
85    /**
86     * Millisecond factory.
87     *
88     * @param value Millisecond string 0-999
89     * @return Millisecond object
90     */
91    public static Millisecond of(final String value)
92     {
93      return of(Integer.parseInt(value));
94     }
95  
96  
97    /**
98     * Returns the value of this Millisecond as an int.
99     *
100    * @return The numeric value represented by this object after conversion to type int (0-999).
101    */
102   public int intValue()
103    {
104     return this.millisecond;
105    }
106 
107 
108   /**
109    * Returns the value of this Millisecond as an String.
110    *
111    * @return The numeric value represented by this object after conversion to type String (0-999).
112    */
113   @Override
114   public String stringValue()
115    {
116     return String.valueOf(this.millisecond);
117    }
118 
119 
120   /**
121    * Calculate hash code.
122    *
123    * @return Hash
124    * @see java.lang.Object#hashCode()
125    */
126   @Override
127   public int hashCode()
128    {
129     return Integer.hashCode(this.millisecond);
130    }
131 
132 
133   /**
134    * Is equal with another object.
135    *
136    * @param obj Object
137    * @return true when equal, false otherwise
138    * @see java.lang.Object#equals(java.lang.Object)
139    */
140   @Override
141   public boolean equals(final Object obj)
142    {
143     if (this == obj)
144      {
145       return true;
146      }
147     if (!(obj instanceof Millisecond))
148      {
149       return false;
150      }
151     final Millisecond other = (Millisecond)obj;
152     return this.millisecond == other.millisecond;
153    }
154 
155 
156   /**
157    * Returns the string representation of this Millisecond.
158    *
159    * The exact details of this representation are unspecified and subject to change, but the following may be regarded as typical:
160    *
161    * "Millisecond[millisecond=0]"
162    *
163    * @return String representation of this Millisecond
164    * @see java.lang.Object#toString()
165    */
166   @Override
167   public String toString()
168    {
169     final var builder = new StringBuilder(25);
170     builder.append("Millisecond[millisecond=").append(this.millisecond).append(']'); //$NON-NLS-1$
171     return builder.toString();
172    }
173 
174 
175   /**
176    * Compare with another object.
177    *
178    * @param obj Object to compare with
179    * @return 0: equal; 1: greater; -1: smaller
180    * @see java.lang.Comparable#compareTo(java.lang.Object)
181    */
182   @Override
183   public int compareTo(final Millisecond obj)
184    {
185     Objects.requireNonNull(obj, "obj"); //$NON-NLS-1$
186     return Integer.compare(this.millisecond, obj.millisecond);
187    }
188 
189 
190   /**
191    * Add milliseconds to this millisecond.
192    *
193    * @param milliseconds Milliseconds to add to this millisecond
194    * @return New millisecond after adding the milliseconds to this millisecond
195    * @throws ArithmeticException In case of an overflow
196    */
197   public Millisecond add(final Milliseconds milliseconds)
198    {
199     final int newMillisecond = Math.toIntExact(Math.addExact(this.millisecond, milliseconds.longValue()));
200     if (newMillisecond > 999)
201      {
202       // TODO Listener
203       throw new ArithmeticException(Millisecond.OVERFLOW);
204      }
205     return Millisecond.of(newMillisecond);
206    }
207 
208 
209   /**
210    * Subtract milliseconds from this millisecond.
211    *
212    * @param milliseconds Milliseconds to subtract from this millisecond
213    * @return New millisecond after subtracting milliseconds from this millisecond
214    * @throws ArithmeticException In case of an underflow
215    */
216   public Millisecond subtract(final Milliseconds milliseconds)
217    {
218     final int newMillisecond = Math.toIntExact(Math.subtractExact(this.millisecond, milliseconds.longValue()));
219     if (newMillisecond < 0)
220      {
221       // TODO Listener
222       throw new ArithmeticException(Millisecond.UNDERFLOW);
223      }
224     return Millisecond.of(newMillisecond);
225    }
226 
227 
228   /**
229    * Increment this millisecond.
230    *
231    * @return New millisecond after incrementing this millisecond
232    * @throws ArithmeticException In case of an overflow
233    */
234   public Millisecond increment()
235    {
236     final int newMillisecond = Math.incrementExact(this.millisecond);
237     if (newMillisecond == 1000)
238      {
239       // TODO Listener
240       throw new ArithmeticException(Millisecond.OVERFLOW);
241      }
242     return Millisecond.of(newMillisecond);
243    }
244 
245 
246   /**
247    * Decrement this millisecond.
248    *
249    * @return New millisecond after decrement this millisecond
250    * @throws ArithmeticException In case of an overflow
251    */
252   public Millisecond decrement()
253    {
254     final int newMillisecond = Math.decrementExact(this.millisecond);
255     if (newMillisecond == -1)
256      {
257       // TODO Listener
258       throw new ArithmeticException(Millisecond.UNDERFLOW);
259      }
260     return Millisecond.of(newMillisecond);
261    }
262 
263  }