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