View Javadoc
1   /*
2    * MoneyWise: Finance Application
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  package io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.base;
18  
19  import io.github.tonywasher.joceanus.oceanus.date.OceanusDate;
20  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusDecimal;
21  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
22  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusPrice;
23  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusRate;
24  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusRatio;
25  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusUnits;
26  import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
27  import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataMap;
28  import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataObjectFormat;
29  
30  import java.util.EnumMap;
31  import java.util.Map;
32  
33  /**
34   * Values for a bucket.
35   *
36   * @param <T> the values class
37   * @param <E> the enum class
38   */
39  public abstract class MoneyWiseAnalysisValues<T extends MoneyWiseAnalysisValues<T, E>, E extends Enum<E> & MoneyWiseAnalysisAttribute>
40          implements MetisDataObjectFormat, MetisDataMap<E, Object> {
41      /**
42       * Map.
43       */
44      private final Map<E, Object> theMap;
45  
46      /**
47       * Enum class.
48       */
49      private final Class<E> theClass;
50  
51      /**
52       * Constructor.
53       *
54       * @param pClass the Enum class
55       */
56      protected MoneyWiseAnalysisValues(final Class<E> pClass) {
57          theMap = new EnumMap<>(pClass);
58          theClass = pClass;
59      }
60  
61      /**
62       * Constructor.
63       *
64       * @param pSource       the source values
65       * @param pCountersOnly only copy counters
66       */
67      protected MoneyWiseAnalysisValues(final T pSource,
68                                        final boolean pCountersOnly) {
69          this(pSource.getEnumClass());
70  
71          /* Loop through the constants */
72          for (E myKey : theClass.getEnumConstants()) {
73              /* If we are copying all or the attribute is a counter */
74              if (!pCountersOnly
75                      || myKey.isCounter()) {
76                  /* Copy non-null values */
77                  final Object myValue = pSource.getValue(myKey);
78                  if (myValue != null) {
79                      theMap.put(myKey, myValue);
80                  }
81              }
82          }
83      }
84  
85      @Override
86      public String formatObject(final OceanusDataFormatter pFormatter) {
87          return getClass().getSimpleName();
88      }
89  
90      /**
91       * Obtain EnumClass.
92       *
93       * @return the class.
94       */
95      protected Class<E> getEnumClass() {
96          return theClass;
97      }
98  
99      /**
100      * Obtain counter snapShot.
101      *
102      * @return the snapShot.
103      */
104     protected abstract T getCounterSnapShot();
105 
106     /**
107      * Obtain full snapShot.
108      *
109      * @return the snapShot.
110      */
111     protected abstract T getFullSnapShot();
112 
113     @Override
114     public Map<E, Object> getUnderlyingMap() {
115         return theMap;
116     }
117 
118     /**
119      * Adjust to base values.
120      *
121      * @param pBaseValues the base values.
122      */
123     protected void adjustToBaseValues(final T pBaseValues) {
124     }
125 
126     /**
127      * Obtain delta value.
128      *
129      * @param pPrevious the previous values.
130      * @param pAttr     the attribute
131      * @return the delta
132      */
133     protected OceanusDecimal getDeltaValue(final T pPrevious,
134                                            final E pAttr) {
135         switch (pAttr.getDataType()) {
136             case MONEY:
137                 return getDeltaMoneyValue(pPrevious, pAttr);
138             case UNITS:
139                 return getDeltaUnitsValue(pPrevious, pAttr);
140             default:
141                 return null;
142         }
143     }
144 
145     /**
146      * Obtain delta money value.
147      *
148      * @param pPrevious the previous values.
149      * @param pAttr     the attribute
150      * @return the delta
151      */
152     protected OceanusMoney getDeltaMoneyValue(final T pPrevious,
153                                               final E pAttr) {
154         /* Access current and previous values */
155         OceanusMoney myCurr = getMoneyValue(pAttr);
156         if (pPrevious != null) {
157             final OceanusMoney myPrev = pPrevious.getMoneyValue(pAttr);
158 
159             /* Calculate delta */
160             myCurr = new OceanusMoney(myCurr);
161             myCurr.subtractAmount(myPrev);
162         }
163         return myCurr;
164     }
165 
166     /**
167      * Obtain delta units value.
168      *
169      * @param pPrevious the previous values.
170      * @param pAttr     the attribute
171      * @return the delta
172      */
173     protected OceanusUnits getDeltaUnitsValue(final T pPrevious,
174                                               final E pAttr) {
175         /* Access current and previous values */
176         OceanusUnits myCurr = getUnitsValue(pAttr);
177         if (pPrevious != null) {
178             final OceanusUnits myPrev = pPrevious.getUnitsValue(pAttr);
179 
180             /* Calculate delta */
181             myCurr = new OceanusUnits(myCurr);
182             myCurr.subtractUnits(myPrev);
183         }
184         return myCurr;
185     }
186 
187     /**
188      * Adjust money value relative to base.
189      *
190      * @param pBase the base values.
191      * @param pAttr the attribute to reBase.
192      */
193     protected void adjustMoneyToBase(final T pBase,
194                                      final E pAttr) {
195         /* Adjust spend values */
196         OceanusMoney myValue = getMoneyValue(pAttr);
197         myValue = new OceanusMoney(myValue);
198         final OceanusMoney myBaseValue = pBase.getMoneyValue(pAttr);
199         myValue.subtractAmount(myBaseValue);
200         theMap.put(pAttr, myValue);
201     }
202 
203     /**
204      * Reset base values.
205      */
206     protected void resetBaseValues() {
207     }
208 
209     /**
210      * Set Value.
211      *
212      * @param pAttr  the attribute
213      * @param pValue the value of the attribute
214      */
215     public void setValue(final E pAttr,
216                          final Object pValue) {
217         /* Set the value into the map */
218         theMap.put(pAttr, pValue);
219     }
220 
221     /**
222      * Obtain an attribute value.
223      *
224      * @param <X>    the data type
225      * @param pAttr  the attribute
226      * @param pClass the class of the attribute
227      * @return the value of the attribute or null
228      */
229     private <X> X getValue(final E pAttr,
230                            final Class<X> pClass) {
231         /* Obtain the value */
232         return pClass.cast(getValue(pAttr));
233     }
234 
235     /**
236      * Obtain an attribute value.
237      *
238      * @param pAttr the attribute
239      * @return the value of the attribute or null
240      */
241     public Object getValue(final E pAttr) {
242         /* Obtain the attribute value */
243         return theMap.get(pAttr);
244     }
245 
246     /**
247      * Obtain a decimal attribute value.
248      *
249      * @param pAttr the attribute
250      * @return the value of the attribute or null
251      */
252     public OceanusDecimal getDecimalValue(final E pAttr) {
253         /* Obtain the attribute value */
254         return getValue(pAttr, OceanusDecimal.class);
255     }
256 
257     /**
258      * Obtain a units attribute value.
259      *
260      * @param pAttr the attribute
261      * @return the value of the attribute or null
262      */
263     public OceanusUnits getUnitsValue(final E pAttr) {
264         /* Obtain the attribute value */
265         return getValue(pAttr, OceanusUnits.class);
266     }
267 
268     /**
269      * Obtain a price attribute value.
270      *
271      * @param pAttr the attribute
272      * @return the value of the attribute or null
273      */
274     public OceanusPrice getPriceValue(final E pAttr) {
275         /* Obtain the attribute value */
276         return getValue(pAttr, OceanusPrice.class);
277     }
278 
279     /**
280      * Obtain a money attribute value.
281      *
282      * @param pAttr the attribute
283      * @return the value of the attribute or null
284      */
285     public OceanusMoney getMoneyValue(final E pAttr) {
286         /* Obtain the attribute value */
287         return getValue(pAttr, OceanusMoney.class);
288     }
289 
290     /**
291      * Obtain a rate attribute value.
292      *
293      * @param pAttr the attribute
294      * @return the value of the attribute or null
295      */
296     public OceanusRate getRateValue(final E pAttr) {
297         /* Obtain the attribute value */
298         return getValue(pAttr, OceanusRate.class);
299     }
300 
301     /**
302      * Obtain a ratio attribute value.
303      *
304      * @param pAttr the attribute
305      * @return the value of the attribute or null
306      */
307     public OceanusRatio getRatioValue(final E pAttr) {
308         /* Obtain the attribute value */
309         return getValue(pAttr, OceanusRatio.class);
310     }
311 
312     /**
313      * Obtain a date attribute value.
314      *
315      * @param pAttr the attribute
316      * @return the value of the attribute or null
317      */
318     public OceanusDate getDateValue(final E pAttr) {
319         /* Obtain the attribute value */
320         return getValue(pAttr, OceanusDate.class);
321     }
322 
323     /**
324      * Obtain an integer attribute value.
325      *
326      * @param pAttr the attribute
327      * @return the value of the attribute or null
328      */
329     public Integer getIntegerValue(final E pAttr) {
330         /* Obtain the attribute */
331         return getValue(pAttr, Integer.class);
332     }
333 
334     /**
335      * Obtain an enum attribute value.
336      *
337      * @param <V>    the enum type
338      * @param pAttr  the attribute
339      * @param pClass the Class of the enum
340      * @return the value of the attribute or null
341      */
342     public <V extends Enum<V>> V getEnumValue(final E pAttr,
343                                               final Class<V> pClass) {
344         /* Obtain the attribute */
345         return getValue(pAttr, pClass);
346     }
347 }