1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.moneywise.data.basic;
18
19 import io.github.tonywasher.joceanus.metis.data.MetisDataDifference;
20 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
21 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataList;
22 import io.github.tonywasher.joceanus.metis.data.MetisDataResource;
23 import io.github.tonywasher.joceanus.metis.field.MetisFieldItem;
24 import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
25 import io.github.tonywasher.joceanus.metis.field.MetisFieldVersionedSet;
26 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCurrency;
27 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCurrency.MoneyWiseCurrencyList;
28 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseStaticResource;
29 import io.github.tonywasher.joceanus.moneywise.exc.MoneyWiseDataException;
30 import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
31 import io.github.tonywasher.joceanus.oceanus.date.OceanusDate;
32 import io.github.tonywasher.joceanus.oceanus.date.OceanusDateFormatter;
33 import io.github.tonywasher.joceanus.oceanus.date.OceanusDateRange;
34 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
35 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusRatio;
36 import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
37 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataInstanceMap;
38 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataItem;
39 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataList;
40 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataMapItem;
41 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataValues;
42
43 import java.util.ArrayList;
44 import java.util.Currency;
45 import java.util.HashMap;
46 import java.util.Iterator;
47 import java.util.List;
48 import java.util.ListIterator;
49 import java.util.Map;
50
51
52
53
54 public class MoneyWiseExchangeRate
55 extends PrometheusDataItem {
56
57
58
59 public static final String OBJECT_NAME = MoneyWiseBasicDataType.EXCHANGERATE.getItemName();
60
61
62
63
64 public static final String LIST_NAME = MoneyWiseBasicDataType.EXCHANGERATE.getListName();
65
66
67
68
69 private static final MetisFieldVersionedSet<MoneyWiseExchangeRate> FIELD_DEFS = MetisFieldVersionedSet.newVersionedFieldSet(MoneyWiseExchangeRate.class);
70
71
72
73
74 static {
75 FIELD_DEFS.declareDateField(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE);
76 FIELD_DEFS.declareLinkField(MoneyWiseBasicResource.XCHGRATE_FROM);
77 FIELD_DEFS.declareLinkField(MoneyWiseBasicResource.XCHGRATE_TO);
78 FIELD_DEFS.declareRatioField(MoneyWiseBasicResource.XCHGRATE_RATE);
79 }
80
81
82
83
84 public static final String ERROR_CIRCLE = MoneyWiseBasicResource.XCHGRATE_ERROR_CIRCLE.getValue();
85
86
87
88
89 public static final String ERROR_DEF = MoneyWiseBasicResource.XCHGRATE_ERROR_DEFAULT.getValue();
90
91
92
93
94
95
96
97 protected MoneyWiseExchangeRate(final MoneyWiseExchangeRateBaseList<? extends MoneyWiseExchangeRate> pList,
98 final MoneyWiseExchangeRate pRate) {
99
100 super(pList, pRate);
101 }
102
103
104
105
106
107
108 public MoneyWiseExchangeRate(final MoneyWiseExchangeRateBaseList<? extends MoneyWiseExchangeRate> pList) {
109 super(pList, 0);
110 }
111
112
113
114
115
116
117
118
119 private MoneyWiseExchangeRate(final MoneyWiseExchangeRateList pList,
120 final PrometheusDataValues pValues) throws OceanusException {
121
122 super(pList, pValues);
123
124
125 final OceanusDataFormatter myFormatter = getDataSet().getDataFormatter();
126
127
128 try {
129
130 Object myValue = pValues.getValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE);
131 if (myValue instanceof OceanusDate d) {
132 setValueDate(d);
133 } else if (myValue instanceof String s) {
134 final OceanusDateFormatter myParser = myFormatter.getDateFormatter();
135 setValueDate(myParser.parseDate(s));
136 }
137
138
139 myValue = pValues.getValue(MoneyWiseBasicResource.XCHGRATE_FROM);
140 if (myValue instanceof Integer i) {
141 setValueFromCurrency(i);
142 } else if (myValue instanceof String s) {
143 setValueFromCurrency(s);
144 }
145
146
147 myValue = pValues.getValue(MoneyWiseBasicResource.XCHGRATE_TO);
148 if (myValue instanceof Integer i) {
149 setValueToCurrency(i);
150 } else if (myValue instanceof String s) {
151 setValueToCurrency(s);
152 }
153
154
155 myValue = pValues.getValue(MoneyWiseBasicResource.XCHGRATE_RATE);
156 if (myValue instanceof OceanusRatio r) {
157 setValueExchangeRate(r);
158 } else if (myValue instanceof String myString) {
159 setValueExchangeRate(myString);
160 setValueExchangeRate(myFormatter.parseValue(myString, OceanusRatio.class));
161 }
162
163
164 } catch (IllegalArgumentException e) {
165
166 throw new MoneyWiseDataException(this, ERROR_CREATEITEM, e);
167 }
168 }
169
170
171
172
173
174
175 public MoneyWiseExchangeRate(final MoneyWiseExchangeRateList pList) {
176 super(pList, 0);
177 }
178
179 @Override
180 public MetisFieldSetDef getDataFieldSet() {
181 return FIELD_DEFS;
182 }
183
184 @Override
185 public String formatObject(final OceanusDataFormatter pFormatter) {
186 return toString();
187 }
188
189 @Override
190 public String toString() {
191
192 final OceanusDataFormatter myFormatter = getDataSet().getDataFormatter();
193
194
195 final StringBuilder myBuilder = new StringBuilder();
196 myBuilder.append(myFormatter.formatObject(getDate()));
197 myBuilder.append(" ");
198 myBuilder.append(myFormatter.formatObject(getFromCurrency().getCurrency().getCurrencyCode()));
199 myBuilder.append(": ");
200 myBuilder.append(myFormatter.formatObject(getToCurrency().getCurrency().getCurrencyCode()));
201 myBuilder.append('=');
202 myBuilder.append(myFormatter.formatObject(getExchangeRate()));
203 return myBuilder.toString();
204 }
205
206 @Override
207 public boolean includeXmlField(final MetisDataFieldId pField) {
208
209 if (MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE.equals(pField)) {
210 return true;
211 }
212 if (MoneyWiseBasicResource.XCHGRATE_FROM.equals(pField)) {
213 return true;
214 }
215 if (MoneyWiseBasicResource.XCHGRATE_TO.equals(pField)) {
216 return true;
217 }
218 if (MoneyWiseBasicResource.XCHGRATE_RATE.equals(pField)) {
219 return true;
220 }
221
222
223 return super.includeXmlField(pField);
224 }
225
226
227
228
229
230
231 public OceanusDate getDate() {
232 return getValues().getValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE, OceanusDate.class);
233 }
234
235
236
237
238
239
240 public MoneyWiseCurrency getFromCurrency() {
241 return getValues().getValue(MoneyWiseBasicResource.XCHGRATE_FROM, MoneyWiseCurrency.class);
242 }
243
244
245
246
247
248
249 public Integer getFromCurrencyId() {
250 final MoneyWiseCurrency myCurr = getFromCurrency();
251 return myCurr == null
252 ? null
253 : myCurr.getIndexedId();
254 }
255
256
257
258
259
260
261 public String getFromCurrencyName() {
262 final MoneyWiseCurrency myCurr = getFromCurrency();
263 return myCurr == null
264 ? null
265 : myCurr.getName();
266 }
267
268
269
270
271
272
273 public MoneyWiseCurrency getToCurrency() {
274 return getValues().getValue(MoneyWiseBasicResource.XCHGRATE_TO, MoneyWiseCurrency.class);
275 }
276
277
278
279
280
281
282 public Integer getToCurrencyId() {
283 final MoneyWiseCurrency myCurr = getToCurrency();
284 return myCurr == null
285 ? null
286 : myCurr.getIndexedId();
287 }
288
289
290
291
292
293
294 public String getToCurrencyName() {
295 final MoneyWiseCurrency myCurr = getToCurrency();
296 return myCurr == null
297 ? null
298 : myCurr.getName();
299 }
300
301
302
303
304
305
306 public OceanusRatio getExchangeRate() {
307 return getValues().getValue(MoneyWiseBasicResource.XCHGRATE_RATE, OceanusRatio.class);
308 }
309
310
311
312
313
314
315 public OceanusRatio getInverseRate() {
316 final OceanusRatio myRate = getExchangeRate();
317 return myRate == null
318 ? null
319 : myRate.getInverseRatio();
320 }
321
322
323
324
325
326
327 private void setValueDate(final OceanusDate pValue) {
328 getValues().setUncheckedValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE, pValue);
329 }
330
331
332
333
334
335
336 private void setValueFromCurrency(final MoneyWiseCurrency pValue) {
337 getValues().setUncheckedValue(MoneyWiseBasicResource.XCHGRATE_FROM, pValue);
338 }
339
340
341
342
343
344
345 private void setValueFromCurrency(final Integer pValue) {
346 getValues().setUncheckedValue(MoneyWiseBasicResource.XCHGRATE_FROM, pValue);
347 }
348
349
350
351
352
353
354 private void setValueFromCurrency(final String pValue) {
355 getValues().setUncheckedValue(MoneyWiseBasicResource.XCHGRATE_FROM, pValue);
356 }
357
358
359
360
361
362
363 private void setValueToCurrency(final MoneyWiseCurrency pValue) {
364 getValues().setUncheckedValue(MoneyWiseBasicResource.XCHGRATE_TO, pValue);
365 }
366
367
368
369
370
371
372 private void setValueToCurrency(final Integer pValue) {
373 getValues().setUncheckedValue(MoneyWiseBasicResource.XCHGRATE_TO, pValue);
374 }
375
376
377
378
379
380
381 private void setValueToCurrency(final String pValue) {
382 getValues().setUncheckedValue(MoneyWiseBasicResource.XCHGRATE_TO, pValue);
383 }
384
385
386
387
388
389
390 protected void setValueExchangeRate(final OceanusRatio pValue) {
391 getValues().setUncheckedValue(MoneyWiseBasicResource.XCHGRATE_RATE, pValue);
392 }
393
394
395
396
397
398
399 private void setValueExchangeRate(final String pValue) {
400 getValues().setUncheckedValue(MoneyWiseBasicResource.XCHGRATE_RATE, pValue);
401 }
402
403 @Override
404 public MoneyWiseDataSet getDataSet() {
405 return (MoneyWiseDataSet) super.getDataSet();
406 }
407
408 @Override
409 public MoneyWiseExchangeRate getBase() {
410 return (MoneyWiseExchangeRate) super.getBase();
411 }
412
413 @Override
414 @SuppressWarnings("unchecked")
415 public MoneyWiseExchangeRateBaseList<? extends MoneyWiseExchangeRate> getList() {
416 return (MoneyWiseExchangeRateBaseList<? extends MoneyWiseExchangeRate>) super.getList();
417 }
418
419 @Override
420 public int compareValues(final PrometheusDataItem pThat) {
421
422 final MoneyWiseExchangeRate myThat = (MoneyWiseExchangeRate) pThat;
423
424
425 int iDiff = MetisDataDifference.compareObject(getDate(), myThat.getDate());
426 if (iDiff != 0) {
427
428 return -iDiff;
429 }
430
431
432 iDiff = MetisDataDifference.compareObject(getFromCurrency(), myThat.getFromCurrency());
433 if (iDiff != 0) {
434 return iDiff;
435 }
436
437
438 return getToCurrency().compareTo(myThat.getToCurrency());
439 }
440
441 @Override
442 public void resolveDataSetLinks() throws OceanusException {
443
444 super.resolveDataSetLinks();
445
446
447 final MoneyWiseDataSet myData = getDataSet();
448 final MoneyWiseCurrencyList myCurrencies = myData.getAccountCurrencies();
449 resolveDataLink(MoneyWiseBasicResource.XCHGRATE_FROM, myCurrencies);
450 resolveDataLink(MoneyWiseBasicResource.XCHGRATE_TO, myCurrencies);
451 }
452
453
454
455
456
457
458 public void setDate(final OceanusDate pDate) {
459 setValueDate(pDate);
460 }
461
462
463
464
465
466
467 public void setFromCurrency(final MoneyWiseCurrency pCurrency) {
468 setValueFromCurrency(pCurrency);
469 }
470
471
472
473
474
475
476 public void setToCurrency(final MoneyWiseCurrency pCurrency) {
477 setValueToCurrency(pCurrency);
478 }
479
480
481
482
483
484
485 public void setExchangeRate(final OceanusRatio pRate) {
486 setValueExchangeRate(pRate);
487 }
488
489 @Override
490 public void touchUnderlyingItems() {
491
492 getFromCurrency().touchItem(this);
493 getToCurrency().touchItem(this);
494 }
495
496
497
498
499
500
501
502 @Override
503 public boolean applyChanges(final PrometheusDataItem pRate) {
504
505 if (!(pRate instanceof MoneyWiseExchangeRate myRate)) {
506 return false;
507 }
508
509
510 pushHistory();
511
512
513 if (!MetisDataDifference.isEqual(getDate(), myRate.getDate())) {
514 setValueDate(myRate.getDate());
515 }
516
517
518 if (!MetisDataDifference.isEqual(getFromCurrency(), myRate.getFromCurrency())) {
519 setValueFromCurrency(myRate.getFromCurrency());
520 }
521
522
523 if (!MetisDataDifference.isEqual(getToCurrency(), myRate.getToCurrency())) {
524 setValueToCurrency(myRate.getToCurrency());
525 }
526
527
528 if (!MetisDataDifference.isEqual(getExchangeRate(), myRate.getExchangeRate())) {
529 setValueExchangeRate(myRate.getExchangeRate());
530 }
531
532
533 return checkForHistory();
534 }
535
536 @Override
537 public void adjustMapForItem() {
538 final MoneyWiseExchangeRateBaseList<? extends MoneyWiseExchangeRate> myList = getList();
539 final MoneyWiseExchangeRateDataMap myMap = myList.getDataMap();
540 myMap.adjustForItem(this);
541 }
542
543
544
545
546
547
548 public abstract static class MoneyWiseExchangeRateBaseList<T extends MoneyWiseExchangeRate>
549 extends PrometheusDataList<T> {
550
551
552
553 static {
554 MetisFieldSet.newFieldSet(MoneyWiseExchangeRateBaseList.class);
555 }
556
557
558
559
560
561
562
563
564 protected MoneyWiseExchangeRateBaseList(final MoneyWiseDataSet pData,
565 final Class<T> pClass,
566 final MoneyWiseBasicDataType pItemType) {
567
568 super(pClass, pData, pItemType, PrometheusListStyle.CORE);
569 }
570
571
572
573
574
575
576 protected MoneyWiseExchangeRateBaseList(final MoneyWiseExchangeRateBaseList<T> pSource) {
577
578 super(pSource);
579 }
580
581 @Override
582 public MoneyWiseExchangeRateDataMap getDataMap() {
583 return (MoneyWiseExchangeRateDataMap) super.getDataMap();
584 }
585
586 @Override
587 protected MoneyWiseExchangeRateDataMap allocateDataMap() {
588 return new MoneyWiseExchangeRateDataMap();
589 }
590 }
591
592
593
594
595 public static class MoneyWiseExchangeRateList
596 extends MoneyWiseExchangeRateBaseList<MoneyWiseExchangeRate> {
597
598
599
600 private static final MetisFieldSet<MoneyWiseExchangeRateList> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseExchangeRateList.class);
601
602
603
604
605 static {
606 FIELD_DEFS.declareLocalField(MoneyWiseStaticResource.CURRENCY_REPORTING, MoneyWiseExchangeRateList::getReportingCurrency);
607 }
608
609
610
611
612 private MoneyWiseCurrency theReporting;
613
614
615
616
617
618
619 protected MoneyWiseExchangeRateList(final MoneyWiseDataSet pData) {
620 super(pData, MoneyWiseExchangeRate.class, MoneyWiseBasicDataType.EXCHANGERATE);
621 }
622
623
624
625
626
627
628 protected MoneyWiseExchangeRateList(final MoneyWiseExchangeRateList pSource) {
629 super(pSource);
630 }
631
632 @Override
633 public MetisFieldSet<MoneyWiseExchangeRateList> getDataFieldSet() {
634 return FIELD_DEFS;
635 }
636
637
638
639
640
641
642 public MoneyWiseCurrency getReportingCurrency() {
643 return theReporting;
644 }
645
646 @Override
647 public String listName() {
648 return LIST_NAME;
649 }
650
651 @Override
652 public MetisFieldSetDef getItemFields() {
653 return MoneyWiseExchangeRate.FIELD_DEFS;
654 }
655
656 @Override
657 public MoneyWiseDataSet getDataSet() {
658 return (MoneyWiseDataSet) super.getDataSet();
659 }
660
661 @Override
662 protected MoneyWiseExchangeRateList getEmptyList(final PrometheusListStyle pStyle) {
663 final MoneyWiseExchangeRateList myList = new MoneyWiseExchangeRateList(this);
664 myList.setStyle(pStyle);
665 return myList;
666 }
667
668
669
670
671
672
673
674 @Override
675 public MoneyWiseExchangeRate addCopyItem(final PrometheusDataItem pRate) {
676
677 if (!(pRate instanceof MoneyWiseExchangeRate)) {
678 throw new UnsupportedOperationException();
679 }
680
681 final MoneyWiseExchangeRate myRate = new MoneyWiseExchangeRate(this, (MoneyWiseExchangeRate) pRate);
682 add(myRate);
683 return myRate;
684 }
685
686
687
688
689
690
691 @Override
692 public MoneyWiseExchangeRate addNewItem() {
693 final MoneyWiseExchangeRate myRate = new MoneyWiseExchangeRate(this);
694 add(myRate);
695 return myRate;
696 }
697
698 @Override
699 public MoneyWiseExchangeRate addValuesItem(final PrometheusDataValues pValues)
700 throws OceanusException {
701
702 final MoneyWiseExchangeRate myRate = new MoneyWiseExchangeRate(this, pValues);
703
704
705 if (!isIdUnique(myRate.getIndexedId())) {
706 myRate.addError(ERROR_DUPLICATE, MetisDataResource.DATA_ID);
707 throw new MoneyWiseDataException(myRate, ERROR_VALIDATION);
708 }
709
710
711 add(myRate);
712
713
714 return myRate;
715 }
716
717
718
719
720
721
722
723
724
725 public OceanusMoney convertCurrency(final OceanusMoney pValue,
726 final MoneyWiseCurrency pCurrency,
727 final OceanusDate pDate) {
728
729 OceanusMoney myValue = pValue;
730 final MoneyWiseCurrencyList myCurrencies = getDataSet().getAccountCurrencies();
731 final Currency myCurrent = pValue.getCurrency();
732 final Currency myReporting = theReporting.getCurrency();
733 final Currency myTarget = pCurrency.getCurrency();
734
735
736 if (myCurrent.equals(myTarget)) {
737 return pValue;
738 }
739
740
741 if (!myCurrent.equals(myReporting)) {
742
743 final OceanusRatio myRate = findRate(myCurrencies.findCurrency(myCurrent), pDate);
744
745
746 myValue = myValue.convertCurrency(myReporting, myRate);
747 }
748
749
750 if (!myReporting.equals(myTarget)) {
751
752 final OceanusRatio myRate = findRate(pCurrency, pDate);
753
754
755 myValue = myValue.convertCurrency(myTarget, myRate);
756 }
757
758
759 return myValue;
760 }
761
762
763
764
765
766
767
768
769 private OceanusRatio findRate(final MoneyWiseCurrency pCurrency,
770 final OceanusDate pDate) {
771
772 return getDataMap().getRateForDate(pCurrency, pDate);
773 }
774
775
776
777
778
779
780 public void setReportingCurrency(final MoneyWiseCurrency pCurrency) {
781
782 final Iterator<MoneyWiseExchangeRate> myIterator = iterator();
783 OceanusRatio myCurrRate = null;
784 OceanusDate myCurrDate = null;
785
786
787 while (myIterator.hasNext()) {
788 final MoneyWiseExchangeRate myCurr = myIterator.next();
789
790
791 final OceanusDate myDate = myCurr.getDate();
792 final MoneyWiseCurrency myTo = myCurr.getToCurrency();
793 final OceanusRatio myRatio = myCurr.getExchangeRate();
794
795
796 if (myCurrDate == null || !myDate.equals(myCurrDate)) {
797
798
799
800
801
802 myCurrRate = findRate(pCurrency, myDate);
803 myCurrDate = myDate;
804 }
805
806
807 myCurr.pushHistory();
808
809
810 if (myTo.equals(pCurrency)) {
811
812 myCurr.setToCurrency(myCurr.getFromCurrency());
813
814
815 myCurr.setExchangeRate(myRatio.getInverseRatio());
816
817
818 } else {
819
820 myCurr.setExchangeRate(new OceanusRatio(myRatio, myCurrRate));
821 }
822
823
824 myCurr.setFromCurrency(pCurrency);
825 }
826
827
828 theReporting = pCurrency;
829 }
830 }
831
832
833
834
835 public static class MoneyWiseExchangeRateDataMap
836 implements PrometheusDataMapItem, MetisFieldItem {
837
838
839
840 @SuppressWarnings("rawtypes")
841 private static final MetisFieldSet<MoneyWiseExchangeRateDataMap> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseExchangeRateDataMap.class);
842
843
844
845
846 static {
847 FIELD_DEFS.declareLocalField(MoneyWiseBasicResource.MONEYWISEDATA_MAP_MAPOFMAPS, MoneyWiseExchangeRateDataMap::getMapOfMaps);
848 FIELD_DEFS.declareLocalField(MoneyWiseBasicResource.XCHGRATE_MAP_MAPOFRATES, MoneyWiseExchangeRateDataMap::getMapOfRates);
849 }
850
851
852
853
854 private final Map<MoneyWiseCurrency, Map<OceanusDate, Integer>> theMapOfMaps;
855
856
857
858
859 private final Map<MoneyWiseCurrency, MoneyWiseRateList> theMapOfRates;
860
861
862
863
864 public MoneyWiseExchangeRateDataMap() {
865
866 theMapOfMaps = new HashMap<>();
867 theMapOfRates = new HashMap<>();
868 }
869
870 @SuppressWarnings("rawtypes")
871 @Override
872 public MetisFieldSet<MoneyWiseExchangeRateDataMap> getDataFieldSet() {
873 return FIELD_DEFS;
874 }
875
876 @Override
877 public String formatObject(final OceanusDataFormatter pFormatter) {
878 return FIELD_DEFS.getName();
879 }
880
881
882
883
884
885
886 private Map<MoneyWiseCurrency, Map<OceanusDate, Integer>> getMapOfMaps() {
887 return theMapOfMaps;
888 }
889
890
891
892
893
894
895 private Map<MoneyWiseCurrency, MoneyWiseRateList> getMapOfRates() {
896 return theMapOfRates;
897 }
898
899 @Override
900 public void resetMap() {
901 theMapOfMaps.clear();
902 theMapOfRates.clear();
903 }
904
905 @Override
906 public void adjustForItem(final PrometheusDataItem pItem) {
907
908 final MoneyWiseExchangeRate myItem = (MoneyWiseExchangeRate) pItem;
909 final MoneyWiseCurrency myCurrency = myItem.getToCurrency();
910 if (myCurrency == null) {
911 return;
912 }
913
914
915 final Map<OceanusDate, Integer> myMap = theMapOfMaps.computeIfAbsent(myCurrency, c -> new HashMap<>());
916
917
918 final OceanusDate myDate = myItem.getDate();
919 final Integer myCount = myMap.get(myDate);
920 if (myCount == null) {
921 myMap.put(myDate, PrometheusDataInstanceMap.ONE);
922 } else {
923 myMap.put(myDate, myCount + 1);
924 }
925
926
927 final MoneyWiseRateList myList = theMapOfRates.computeIfAbsent(myCurrency, MoneyWiseRateList::new);
928
929
930 myList.add(myItem);
931 }
932
933
934
935
936
937
938
939 public boolean validRateCount(final MoneyWiseExchangeRate pItem) {
940
941 final MoneyWiseCurrency myCurrency = pItem.getToCurrency();
942 final OceanusDate myDate = pItem.getDate();
943
944
945 final Map<OceanusDate, Integer> myMap = theMapOfMaps.get(myCurrency);
946 if (myMap != null) {
947 final Integer myResult = myMap.get(myDate);
948 return PrometheusDataInstanceMap.ONE.equals(myResult);
949 }
950 return false;
951 }
952
953
954
955
956
957
958
959
960 public boolean availableDate(final MoneyWiseCurrency pCurrency,
961 final OceanusDate pDate) {
962
963 final Map<OceanusDate, Integer> myMap = theMapOfMaps.get(pCurrency);
964 return myMap == null
965 || myMap.get(pDate) == null;
966 }
967
968
969
970
971
972
973
974
975 public OceanusRatio getRateForDate(final MoneyWiseCurrency pCurrency,
976 final OceanusDate pDate) {
977
978 final MoneyWiseRateList myList = theMapOfRates.get(pCurrency);
979 if (myList != null) {
980
981 final Iterator<MoneyWiseExchangeRate> myIterator = myList.iterator();
982 while (myIterator.hasNext()) {
983 final MoneyWiseExchangeRate myCurr = myIterator.next();
984
985
986 final OceanusDate myDate = myCurr.getDate();
987
988
989 if (myDate.compareTo(pDate) >= 0) {
990 return myCurr.getExchangeRate();
991 }
992 }
993 }
994
995
996 return null;
997 }
998
999
1000
1001
1002
1003
1004
1005
1006 public OceanusRatio[] getRatesForRange(final MoneyWiseCurrency pCurrency,
1007 final OceanusDateRange pRange) {
1008
1009 OceanusRatio myFirst = OceanusRatio.ONE;
1010 OceanusRatio myLatest = OceanusRatio.ONE;
1011 final OceanusDate myStart = pRange.getStart();
1012
1013
1014 final MoneyWiseRateList myList = theMapOfRates.get(pCurrency);
1015 if (myList != null) {
1016
1017 final ListIterator<MoneyWiseExchangeRate> myIterator = myList.listIterator(myList.size());
1018 while (myIterator.hasPrevious()) {
1019 final MoneyWiseExchangeRate myCurr = myIterator.previous();
1020
1021
1022 final OceanusDate myDate = myCurr.getDate();
1023 final int iComp = pRange.compareToDate(myDate);
1024
1025
1026 if (iComp < 0) {
1027 break;
1028 }
1029
1030
1031 myLatest = myCurr.getExchangeRate();
1032
1033
1034 if (iComp > 0
1035 || myDate.compareTo(myStart) == 0) {
1036 myFirst = myLatest;
1037 }
1038 }
1039 }
1040
1041
1042 return new OceanusRatio[]
1043 {myFirst, myLatest};
1044 }
1045
1046
1047
1048
1049
1050
1051
1052 public ListIterator<MoneyWiseExchangeRate> rateIterator(final MoneyWiseCurrency pCurrency) {
1053
1054 final MoneyWiseRateList myList = theMapOfRates.get(pCurrency);
1055 return myList != null
1056 ? myList.listIterator(myList.size())
1057 : null;
1058 }
1059
1060
1061
1062
1063 private static final class MoneyWiseRateList
1064 implements MetisFieldItem, MetisDataList<MoneyWiseExchangeRate> {
1065
1066
1067
1068 private static final MetisFieldSet<MoneyWiseRateList> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseRateList.class);
1069
1070
1071
1072
1073 static {
1074 FIELD_DEFS.declareLocalField(MetisDataResource.LIST_SIZE, MoneyWiseRateList::size);
1075 }
1076
1077
1078
1079
1080 private final List<MoneyWiseExchangeRate> theList;
1081
1082
1083
1084
1085 private final MoneyWiseCurrency theCurrency;
1086
1087
1088
1089
1090
1091
1092 private MoneyWiseRateList(final MoneyWiseCurrency pCurrency) {
1093 theCurrency = pCurrency;
1094 theList = new ArrayList<>();
1095 }
1096
1097 @Override
1098 public MetisFieldSet<MoneyWiseRateList> getDataFieldSet() {
1099 return FIELD_DEFS;
1100 }
1101
1102 @Override
1103 public String formatObject(final OceanusDataFormatter pFormatter) {
1104 return theCurrency.formatObject(pFormatter)
1105 + "("
1106 + size()
1107 + ")";
1108 }
1109
1110 @Override
1111 public String toString() {
1112 return theCurrency.toString()
1113 + "("
1114 + size()
1115 + ")";
1116 }
1117
1118 @Override
1119 public List<MoneyWiseExchangeRate> getUnderlyingList() {
1120 return theList;
1121 }
1122 }
1123 }
1124 }