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.atlas.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 MoneyWiseXAnalysisValues<T extends MoneyWiseXAnalysisValues<T, E>, E extends Enum<E> & MoneyWiseXAnalysisAttribute>
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 MoneyWiseXAnalysisValues(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       */
66      protected MoneyWiseXAnalysisValues(final T pSource) {
67          theMap = new EnumMap<>(pSource.getUnderlyingMap());
68          theClass = pSource.getEnumClass();
69      }
70  
71      /**
72       * Reset nonPreserved items.
73       */
74      void resetNonPreserved() {
75          /* Loop through the constants */
76          for (E myKey : theClass.getEnumConstants()) {
77              /* If we are copying all or the attribute is preserved */
78              if (!myKey.isPreserved()) {
79                  /* Remove values that are not preserved */
80                  theMap.remove(myKey);
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 new snapShot.
101      *
102      * @return the snapShot.
103      */
104     protected abstract T newSnapShot();
105 
106     @Override
107     public Map<E, Object> getUnderlyingMap() {
108         return theMap;
109     }
110 
111     /**
112      * Adjust to base values.
113      *
114      * @param pBaseValues the base values.
115      */
116     public void adjustToBaseValues(final T pBaseValues) {
117     }
118 
119     /**
120      * Obtain delta value.
121      *
122      * @param pPrevious the previous values.
123      * @param pAttr     the attribute
124      * @return the delta
125      */
126     protected OceanusDecimal getDeltaValue(final T pPrevious,
127                                            final E pAttr) {
128         switch (pAttr.getDataType()) {
129             case MONEY:
130                 return getDeltaMoneyValue(pPrevious, pAttr);
131             case UNITS:
132                 return getDeltaUnitsValue(pPrevious, pAttr);
133             default:
134                 return null;
135         }
136     }
137 
138     /**
139      * Obtain delta money value.
140      *
141      * @param pPrevious the previous values.
142      * @param pAttr     the attribute
143      * @return the delta
144      */
145     protected OceanusMoney getDeltaMoneyValue(final T pPrevious,
146                                               final E pAttr) {
147         /* Access current and previous values */
148         OceanusMoney myCurr = getMoneyValue(pAttr);
149         if (pPrevious != null) {
150             final OceanusMoney myPrev = pPrevious.getMoneyValue(pAttr);
151 
152             /* Calculate delta */
153             myCurr = new OceanusMoney(myCurr);
154             myCurr.subtractAmount(myPrev);
155         }
156         return myCurr;
157     }
158 
159     /**
160      * Obtain delta units value.
161      *
162      * @param pPrevious the previous values.
163      * @param pAttr     the attribute
164      * @return the delta
165      */
166     protected OceanusUnits getDeltaUnitsValue(final T pPrevious,
167                                               final E pAttr) {
168         /* Access current and previous values */
169         OceanusUnits myCurr = getUnitsValue(pAttr);
170         if (pPrevious != null) {
171             final OceanusUnits myPrev = pPrevious.getUnitsValue(pAttr);
172 
173             /* Calculate delta */
174             myCurr = new OceanusUnits(myCurr);
175             myCurr.subtractUnits(myPrev);
176         }
177         return myCurr;
178     }
179 
180     /**
181      * Adjust money value relative to base.
182      *
183      * @param pBase the base values.
184      * @param pAttr the attribute to reBase.
185      */
186     protected void adjustMoneyToBase(final T pBase,
187                                      final E pAttr) {
188         /* Adjust spend values */
189         OceanusMoney myValue = getMoneyValue(pAttr);
190         myValue = new OceanusMoney(myValue);
191         final OceanusMoney myBaseValue = pBase.getMoneyValue(pAttr);
192         myValue.subtractAmount(myBaseValue);
193         theMap.put(pAttr, myValue);
194     }
195 
196     /**
197      * Reset base values.
198      */
199     public void resetBaseValues() {
200     }
201 
202     /**
203      * Set Value.
204      *
205      * @param pAttr  the attribute
206      * @param pValue the value of the attribute
207      */
208     public void setValue(final E pAttr,
209                          final Object pValue) {
210         /* Set the value into the map */
211         theMap.put(pAttr, pValue);
212     }
213 
214     /**
215      * Obtain an attribute value.
216      *
217      * @param <X>    the data type
218      * @param pAttr  the attribute
219      * @param pClass the class of the attribute
220      * @return the value of the attribute or null
221      */
222     private <X> X getValue(final E pAttr,
223                            final Class<X> pClass) {
224         /* Obtain the value */
225         return pClass.cast(getValue(pAttr));
226     }
227 
228     /**
229      * Obtain an attribute value.
230      *
231      * @param pAttr the attribute
232      * @return the value of the attribute or null
233      */
234     public Object getValue(final E pAttr) {
235         /* Obtain the attribute value */
236         return theMap.get(pAttr);
237     }
238 
239     /**
240      * Obtain a decimal attribute value.
241      *
242      * @param pAttr the attribute
243      * @return the value of the attribute or null
244      */
245     public OceanusDecimal getDecimalValue(final E pAttr) {
246         /* Obtain the attribute value */
247         return getValue(pAttr, OceanusDecimal.class);
248     }
249 
250     /**
251      * Obtain a units attribute value.
252      *
253      * @param pAttr the attribute
254      * @return the value of the attribute or null
255      */
256     public OceanusUnits getUnitsValue(final E pAttr) {
257         /* Obtain the attribute value */
258         return getValue(pAttr, OceanusUnits.class);
259     }
260 
261     /**
262      * Obtain a price attribute value.
263      *
264      * @param pAttr the attribute
265      * @return the value of the attribute or null
266      */
267     public OceanusPrice getPriceValue(final E pAttr) {
268         /* Obtain the attribute value */
269         return getValue(pAttr, OceanusPrice.class);
270     }
271 
272     /**
273      * Obtain a money attribute value.
274      *
275      * @param pAttr the attribute
276      * @return the value of the attribute or null
277      */
278     public OceanusMoney getMoneyValue(final E pAttr) {
279         /* Obtain the attribute value */
280         return getValue(pAttr, OceanusMoney.class);
281     }
282 
283     /**
284      * Obtain a rate attribute value.
285      *
286      * @param pAttr the attribute
287      * @return the value of the attribute or null
288      */
289     public OceanusRate getRateValue(final E pAttr) {
290         /* Obtain the attribute value */
291         return getValue(pAttr, OceanusRate.class);
292     }
293 
294     /**
295      * Obtain a ratio attribute value.
296      *
297      * @param pAttr the attribute
298      * @return the value of the attribute or null
299      */
300     public OceanusRatio getRatioValue(final E pAttr) {
301         /* Obtain the attribute value */
302         return getValue(pAttr, OceanusRatio.class);
303     }
304 
305     /**
306      * Obtain a date attribute value.
307      *
308      * @param pAttr the attribute
309      * @return the value of the attribute or null
310      */
311     public OceanusDate getDateValue(final E pAttr) {
312         /* Obtain the attribute value */
313         return getValue(pAttr, OceanusDate.class);
314     }
315 
316     /**
317      * Obtain an integer attribute value.
318      *
319      * @param pAttr the attribute
320      * @return the value of the attribute or null
321      */
322     public Integer getIntegerValue(final E pAttr) {
323         /* Obtain the attribute */
324         return getValue(pAttr, Integer.class);
325     }
326 
327     /**
328      * Obtain an enum attribute value.
329      *
330      * @param <V>    the enum type
331      * @param pAttr  the attribute
332      * @param pClass the Class of the enum
333      * @return the value of the attribute or null
334      */
335     public <V extends Enum<V>> V getEnumValue(final E pAttr,
336                                               final Class<V> pClass) {
337         /* Obtain the attribute */
338         return getValue(pAttr, pClass);
339     }
340 
341     @Override
342     public String toString() {
343         final StringBuilder myBuilder = new StringBuilder();
344         for (Map.Entry<E, Object> myEntry : theMap.entrySet()) {
345             final Object myValue = myEntry.getValue();
346             if (!(myValue instanceof OceanusDecimal myDec) || myDec.isNonZero()) {
347                 if (!myBuilder.isEmpty()) {
348                     myBuilder.append(", ");
349                 }
350                 myBuilder.append(myEntry.getKey());
351                 myBuilder.append("=");
352                 myBuilder.append(myEntry.getValue());
353             }
354         }
355         return myBuilder.toString();
356     }
357 }