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