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.oceanus.base.OceanusException;
20 import io.github.tonywasher.joceanus.oceanus.date.OceanusDate;
21 import io.github.tonywasher.joceanus.oceanus.date.OceanusDateFormatter;
22 import io.github.tonywasher.joceanus.oceanus.date.OceanusDateRange;
23 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusPrice;
24 import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
25 import io.github.tonywasher.joceanus.metis.data.MetisDataDifference;
26 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
27 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataList;
28 import io.github.tonywasher.joceanus.metis.data.MetisDataResource;
29 import io.github.tonywasher.joceanus.metis.field.MetisFieldItem;
30 import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
31 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurity.MoneyWiseSecurityList;
32 import io.github.tonywasher.joceanus.moneywise.exc.MoneyWiseDataException;
33 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataInstanceMap;
34 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataItem;
35 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataMapItem;
36 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataValues;
37 import io.github.tonywasher.joceanus.prometheus.data.PrometheusEncryptedDataItem;
38 import io.github.tonywasher.joceanus.prometheus.data.PrometheusEncryptedFieldSet;
39 import io.github.tonywasher.joceanus.prometheus.data.PrometheusEncryptedPair;
40 import io.github.tonywasher.joceanus.prometheus.data.PrometheusEncryptedValues;
41 import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
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
55
56 public class MoneyWiseSecurityPrice
57 extends PrometheusEncryptedDataItem {
58
59
60
61 public static final String OBJECT_NAME = MoneyWiseBasicDataType.SECURITYPRICE.getItemName();
62
63
64
65
66 public static final String LIST_NAME = MoneyWiseBasicDataType.SECURITYPRICE.getListName();
67
68
69
70
71 private static final PrometheusEncryptedFieldSet<MoneyWiseSecurityPrice> FIELD_DEFS = PrometheusEncryptedFieldSet.newEncryptedFieldSet(MoneyWiseSecurityPrice.class);
72
73
74
75
76 static {
77 FIELD_DEFS.declareLinkField(MoneyWiseBasicDataType.SECURITY);
78 FIELD_DEFS.declareDateField(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE);
79 FIELD_DEFS.declareEncryptedPriceField(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_PRICE);
80 }
81
82
83
84
85 public static final String ERROR_CURRENCY = MoneyWiseBasicResource.MONEYWISEDATA_ERROR_CURRENCY.getValue();
86
87
88
89
90
91
92
93 protected MoneyWiseSecurityPrice(final MoneyWiseSecurityPriceBaseList<? extends MoneyWiseSecurityPrice> pList,
94 final MoneyWiseSecurityPrice pPrice) {
95
96 super(pList, pPrice);
97 }
98
99
100
101
102
103
104 public MoneyWiseSecurityPrice(final MoneyWiseSecurityPriceBaseList<? extends MoneyWiseSecurityPrice> pList) {
105 super(pList, 0);
106 setNextDataKeySet();
107 }
108
109
110
111
112
113
114
115
116 private MoneyWiseSecurityPrice(final MoneyWiseSecurityPriceList pList,
117 final PrometheusDataValues pValues) throws OceanusException {
118
119 super(pList, pValues);
120
121
122 final OceanusDataFormatter myFormatter = getDataSet().getDataFormatter();
123
124
125 try {
126
127 Object myValue = pValues.getValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE);
128 if (myValue instanceof OceanusDate d) {
129 setValueDate(d);
130 } else if (myValue instanceof String s) {
131 final OceanusDateFormatter myParser = myFormatter.getDateFormatter();
132 setValueDate(myParser.parseDate(s));
133 }
134
135
136 myValue = pValues.getValue(MoneyWiseBasicDataType.SECURITY);
137 if (myValue instanceof Integer i) {
138 setValueSecurity(i);
139 } else if (myValue instanceof String s) {
140 setValueSecurity(s);
141 }
142
143
144 myValue = pValues.getValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_PRICE);
145 if (myValue instanceof OceanusPrice p) {
146 setValuePrice(p);
147 } else if (myValue instanceof byte[] ba) {
148 setValuePrice(ba);
149 } else if (myValue instanceof String myString) {
150 setValuePrice(myString);
151 setValuePrice(myFormatter.parseValue(myString, OceanusPrice.class));
152 }
153
154
155 } catch (IllegalArgumentException
156 | OceanusException e) {
157
158 throw new MoneyWiseDataException(this, ERROR_CREATEITEM, e);
159 }
160 }
161
162 @Override
163 public MetisFieldSetDef getDataFieldSet() {
164 return FIELD_DEFS;
165 }
166
167 @Override
168 public boolean includeXmlField(final MetisDataFieldId pField) {
169
170 if (MoneyWiseBasicDataType.SECURITY.equals(pField)) {
171 return true;
172 }
173 if (MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE.equals(pField)) {
174 return true;
175 }
176 if (MoneyWiseBasicResource.MONEYWISEDATA_FIELD_PRICE.equals(pField)) {
177 return true;
178 }
179
180
181 return super.includeXmlField(pField);
182 }
183
184 @Override
185 public String toString() {
186
187 final PrometheusEncryptedValues myValues = getValues();
188 final Object mySecurity = myValues.getValue(MoneyWiseBasicDataType.SECURITY);
189 final Object myDate = myValues.getValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE);
190 final Object myPrice = myValues.getValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_PRICE, OceanusPrice.class);
191
192
193 final OceanusDataFormatter myFormatter = getDataSet().getDataFormatter();
194
195
196 final StringBuilder myBuilder = new StringBuilder();
197 myBuilder.append(myFormatter.formatObject(mySecurity));
198 myBuilder.append(": ");
199 myBuilder.append(myFormatter.formatObject(myPrice));
200 myBuilder.append('@');
201 myBuilder.append(myFormatter.formatObject(myDate));
202
203
204 return myBuilder.toString();
205 }
206
207 @Override
208 public String formatObject(final OceanusDataFormatter pFormatter) {
209 return toString();
210 }
211
212
213
214
215
216
217 public OceanusPrice getPrice() {
218 return getValues().getValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_PRICE, OceanusPrice.class);
219 }
220
221
222
223
224
225
226 public byte[] getPriceBytes() {
227 return getValues().getEncryptedBytes(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_PRICE);
228 }
229
230
231
232
233
234
235 public PrometheusEncryptedPair getPriceField() {
236 return getValues().getEncryptedPair(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_PRICE);
237 }
238
239
240
241
242
243
244 public OceanusDate getDate() {
245 return getValues().getValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE, OceanusDate.class);
246 }
247
248
249
250
251
252
253 public MoneyWiseSecurity getSecurity() {
254 return getValues().getValue(MoneyWiseBasicDataType.SECURITY, MoneyWiseSecurity.class);
255 }
256
257
258
259
260
261
262 public Integer getSecurityId() {
263 final MoneyWiseSecurity mySecurity = getSecurity();
264 return mySecurity == null
265 ? null
266 : mySecurity.getIndexedId();
267 }
268
269
270
271
272
273
274 public String getSecurityName() {
275 final MoneyWiseSecurity mySecurity = getSecurity();
276 return mySecurity == null
277 ? null
278 : mySecurity.getName();
279 }
280
281
282
283
284
285
286 private void setValueSecurity(final MoneyWiseSecurity pValue) {
287 getValues().setUncheckedValue(MoneyWiseBasicDataType.SECURITY, pValue);
288 }
289
290
291
292
293
294
295 private void setValueSecurity(final Integer pId) {
296 getValues().setUncheckedValue(MoneyWiseBasicDataType.SECURITY, pId);
297 }
298
299
300
301
302
303
304 private void setValueSecurity(final String pName) {
305 getValues().setUncheckedValue(MoneyWiseBasicDataType.SECURITY, pName);
306 }
307
308
309
310
311
312
313
314 private void setValuePrice(final OceanusPrice pValue) throws OceanusException {
315 setEncryptedValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_PRICE, pValue);
316 }
317
318
319
320
321
322
323
324 private void setValuePrice(final byte[] pBytes) throws OceanusException {
325 setEncryptedValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_PRICE, pBytes, OceanusPrice.class);
326 }
327
328
329
330
331
332
333 private void setValuePrice(final String pValue) {
334 getValues().setUncheckedValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_PRICE, pValue);
335 }
336
337
338
339
340
341
342 public void setValuePrice(final PrometheusEncryptedPair pValue) {
343 getValues().setUncheckedValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_PRICE, pValue);
344 }
345
346
347
348
349
350
351 private void setValueDate(final OceanusDate pValue) {
352 getValues().setUncheckedValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE, pValue);
353 }
354
355 @Override
356 public MoneyWiseDataSet getDataSet() {
357 return (MoneyWiseDataSet) super.getDataSet();
358 }
359
360 @Override
361 @SuppressWarnings("unchecked")
362 public MoneyWiseSecurityPriceBaseList<? extends MoneyWiseSecurityPrice> getList() {
363 return (MoneyWiseSecurityPriceBaseList<? extends MoneyWiseSecurityPrice>) super.getList();
364 }
365
366 @Override
367 public MoneyWiseSecurityPrice getBase() {
368 return (MoneyWiseSecurityPrice) super.getBase();
369 }
370
371 @Override
372 public int compareValues(final PrometheusDataItem pThat) {
373
374 final MoneyWiseSecurityPrice myThat = (MoneyWiseSecurityPrice) pThat;
375
376
377 if (isHeader() != pThat.isHeader()) {
378 return isHeader()
379 ? -1
380 : 1;
381 }
382
383
384 final int iDiff = MetisDataDifference.compareObject(getDate(), myThat.getDate());
385 if (iDiff != 0) {
386
387 return -iDiff;
388 }
389
390
391 return getSecurity().compareTo(myThat.getSecurity());
392 }
393
394 @Override
395 public void resolveDataSetLinks() throws OceanusException {
396
397 super.resolveDataSetLinks();
398
399
400 final MoneyWiseDataSet myData = getDataSet();
401 resolveDataLink(MoneyWiseBasicDataType.SECURITY, myData.getSecurities());
402 }
403
404
405
406
407
408
409
410 protected void resolveEditSetLinks(final PrometheusEditSet pEditSet) throws OceanusException {
411
412 final MoneyWiseSecurityList mySecurities = pEditSet.getDataList(MoneyWiseBasicDataType.SECURITY, MoneyWiseSecurityList.class);
413 resolveDataLink(MoneyWiseBasicDataType.SECURITY, mySecurities);
414 }
415
416
417
418
419
420
421 public void setSecurity(final MoneyWiseSecurity pValue) {
422 setValueSecurity(pValue);
423 }
424
425
426
427
428
429
430
431 public void setPrice(final OceanusPrice pPrice) throws OceanusException {
432 setValuePrice(pPrice);
433 }
434
435
436
437
438
439
440 public void setDate(final OceanusDate pDate) {
441 setValueDate(pDate);
442 }
443
444 @Override
445 public void touchUnderlyingItems() {
446
447 getSecurity().touchItem(this);
448 }
449
450 @Override
451 public void touchOnUpdate() {
452
453 getSecurity().touchItem(this);
454 }
455
456 @Override
457 public boolean applyChanges(final PrometheusDataItem pPrice) {
458
459 if (!(pPrice instanceof MoneyWiseSecurityPrice)) {
460 return false;
461 }
462 final MoneyWiseSecurityPrice myPrice = (MoneyWiseSecurityPrice) pPrice;
463
464
465 pushHistory();
466
467
468 if (!MetisDataDifference.isEqual(getPrice(), myPrice.getPrice())) {
469 setValuePrice(myPrice.getPriceField());
470 }
471
472
473 if (!MetisDataDifference.isEqual(getDate(), myPrice.getDate())) {
474 setValueDate(myPrice.getDate());
475 }
476
477
478 return checkForHistory();
479 }
480
481 @Override
482 public void adjustMapForItem() {
483 final MoneyWiseSecurityPriceBaseList<? extends MoneyWiseSecurityPrice> myList = getList();
484 final MoneyWiseSecurityPriceDataMap myMap = myList.getDataMap();
485 myMap.adjustForItem(this);
486 }
487
488
489
490
491
492
493 public abstract static class MoneyWiseSecurityPriceBaseList<T extends MoneyWiseSecurityPrice>
494 extends PrometheusEncryptedList<T> {
495
496
497
498 static {
499 MetisFieldSet.newFieldSet(MoneyWiseSecurityPriceBaseList.class);
500 }
501
502
503
504
505
506
507
508
509 protected MoneyWiseSecurityPriceBaseList(final MoneyWiseDataSet pData,
510 final Class<T> pClass,
511 final MoneyWiseBasicDataType pItemType) {
512
513 super(pClass, pData, pItemType, PrometheusListStyle.CORE);
514 }
515
516
517
518
519
520
521 protected MoneyWiseSecurityPriceBaseList(final MoneyWiseSecurityPriceBaseList<T> pSource) {
522
523 super(pSource);
524 }
525
526 @Override
527 public MoneyWiseSecurityPriceDataMap getDataMap() {
528 return (MoneyWiseSecurityPriceDataMap) super.getDataMap();
529 }
530
531 @Override
532 protected MoneyWiseSecurityPriceDataMap allocateDataMap() {
533 return new MoneyWiseSecurityPriceDataMap();
534 }
535 }
536
537
538
539
540 public static class MoneyWiseSecurityPriceList
541 extends MoneyWiseSecurityPriceBaseList<MoneyWiseSecurityPrice> {
542
543
544
545 private static final MetisFieldSet<MoneyWiseSecurityPriceList> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseSecurityPriceList.class);
546
547
548
549
550
551
552 protected MoneyWiseSecurityPriceList(final MoneyWiseDataSet pData) {
553 super(pData, MoneyWiseSecurityPrice.class, MoneyWiseBasicDataType.SECURITYPRICE);
554 }
555
556
557
558
559
560
561 private MoneyWiseSecurityPriceList(final MoneyWiseSecurityPriceList pSource) {
562 super(pSource);
563 }
564
565 @Override
566 public MetisFieldSet<MoneyWiseSecurityPriceList> getDataFieldSet() {
567 return FIELD_DEFS;
568 }
569
570 @Override
571 public String listName() {
572 return LIST_NAME;
573 }
574
575 @Override
576 public MetisFieldSetDef getItemFields() {
577 return MoneyWiseSecurityPrice.FIELD_DEFS;
578 }
579
580 @Override
581 public MoneyWiseDataSet getDataSet() {
582 return (MoneyWiseDataSet) super.getDataSet();
583 }
584
585 @Override
586 protected MoneyWiseSecurityPriceList getEmptyList(final PrometheusListStyle pStyle) {
587 final MoneyWiseSecurityPriceList myList = new MoneyWiseSecurityPriceList(this);
588 myList.setStyle(pStyle);
589 return myList;
590 }
591
592
593
594
595
596
597
598
599 public MoneyWiseSecurityPriceList deriveEditList(final PrometheusEditSet pEditSet) throws OceanusException {
600
601 final MoneyWiseSecurityPriceList myList = getEmptyList(PrometheusListStyle.EDIT);
602 myList.ensureMap();
603 pEditSet.setEditEntryList(MoneyWiseBasicDataType.SECURITYPRICE, myList);
604
605
606 final Iterator<MoneyWiseSecurityPrice> myIterator = iterator();
607 while (myIterator.hasNext()) {
608 final MoneyWiseSecurityPrice myCurr = myIterator.next();
609
610
611 final MoneyWiseSecurityPrice myItem = new MoneyWiseSecurityPrice(myList, myCurr);
612 myItem.resolveEditSetLinks(pEditSet);
613 myList.add(myItem);
614
615
616 myItem.adjustMapForItem();
617 }
618
619
620 return myList;
621 }
622
623
624
625
626
627
628
629 @Override
630 public MoneyWiseSecurityPrice addCopyItem(final PrometheusDataItem pPrice) {
631 if (pPrice instanceof MoneyWiseSecurityPrice p) {
632 final MoneyWiseSecurityPrice myPrice = new MoneyWiseSecurityPrice(this, p);
633 add(myPrice);
634 return myPrice;
635 } else {
636 throw new UnsupportedOperationException();
637 }
638 }
639
640
641
642
643
644
645 @Override
646 public MoneyWiseSecurityPrice addNewItem() {
647 final MoneyWiseSecurityPrice myPrice = new MoneyWiseSecurityPrice(this);
648 add(myPrice);
649 return myPrice;
650 }
651
652 @Override
653 public MoneyWiseSecurityPrice addValuesItem(final PrometheusDataValues pValues) throws OceanusException {
654
655 final MoneyWiseSecurityPrice myPrice = new MoneyWiseSecurityPrice(this, pValues);
656
657
658 if (!isIdUnique(myPrice.getIndexedId())) {
659 myPrice.addError(ERROR_DUPLICATE, MetisDataResource.DATA_ID);
660 throw new MoneyWiseDataException(myPrice, ERROR_VALIDATION);
661 }
662
663
664 add(myPrice);
665
666
667 return myPrice;
668 }
669 }
670
671
672
673
674 public static class MoneyWiseSecurityPriceDataMap
675 implements PrometheusDataMapItem, MetisFieldItem {
676
677
678
679 @SuppressWarnings("rawtypes")
680 private static final MetisFieldSet<MoneyWiseSecurityPriceDataMap> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseSecurityPriceDataMap.class);
681
682
683
684
685 static {
686 FIELD_DEFS.declareLocalField(MoneyWiseBasicResource.MONEYWISEDATA_MAP_MAPOFMAPS, MoneyWiseSecurityPriceDataMap::getMapOfMaps);
687 FIELD_DEFS.declareLocalField(MoneyWiseBasicResource.SECURITYPRICE_MAP_MAPOFPRICES, MoneyWiseSecurityPriceDataMap::getMapOfPrices);
688 }
689
690
691
692
693 private final Map<MoneyWiseSecurity, Map<OceanusDate, Integer>> theMapOfMaps;
694
695
696
697
698 private final Map<MoneyWiseSecurity, MoneyWiseSecurityPriceList> theMapOfPrices;
699
700
701
702
703 public MoneyWiseSecurityPriceDataMap() {
704
705 theMapOfMaps = new HashMap<>();
706 theMapOfPrices = new HashMap<>();
707 }
708
709 @SuppressWarnings("rawtypes")
710 @Override
711 public MetisFieldSet<MoneyWiseSecurityPriceDataMap> getDataFieldSet() {
712 return FIELD_DEFS;
713 }
714
715 @Override
716 public String formatObject(final OceanusDataFormatter pFormatter) {
717 return FIELD_DEFS.getName();
718 }
719
720
721
722
723
724
725 private Map<MoneyWiseSecurity, Map<OceanusDate, Integer>> getMapOfMaps() {
726 return theMapOfMaps;
727 }
728
729
730
731
732
733
734 private Map<MoneyWiseSecurity, MoneyWiseSecurityPriceList> getMapOfPrices() {
735 return theMapOfPrices;
736 }
737
738 @Override
739 public void resetMap() {
740 theMapOfMaps.clear();
741 theMapOfPrices.clear();
742 }
743
744 @Override
745 public void adjustForItem(final PrometheusDataItem pItem) {
746
747 final MoneyWiseSecurityPrice myItem = (MoneyWiseSecurityPrice) pItem;
748 final MoneyWiseSecurity mySecurity = myItem.getSecurity();
749 if (mySecurity == null) {
750 return;
751 }
752
753
754 final Map<OceanusDate, Integer> myMap = theMapOfMaps.computeIfAbsent(mySecurity, s -> new HashMap<>());
755
756
757 final OceanusDate myDate = myItem.getDate();
758 final Integer myCount = myMap.get(myDate);
759 if (myCount == null) {
760 myMap.put(myDate, PrometheusDataInstanceMap.ONE);
761 } else {
762 myMap.put(myDate, myCount + 1);
763 }
764
765
766 final MoneyWiseSecurityPriceList myList = theMapOfPrices.computeIfAbsent(mySecurity, MoneyWiseSecurityPriceList::new);
767
768
769 myList.add(myItem);
770 }
771
772
773
774
775
776
777
778 public boolean validPriceCount(final MoneyWiseSecurityPrice pItem) {
779
780 final MoneyWiseSecurity mySecurity = pItem.getSecurity();
781 final OceanusDate myDate = pItem.getDate();
782
783
784 final Map<OceanusDate, Integer> myMap = theMapOfMaps.get(mySecurity);
785 if (myMap != null) {
786 final Integer myResult = myMap.get(myDate);
787 return PrometheusDataInstanceMap.ONE.equals(myResult);
788 }
789 return false;
790 }
791
792
793
794
795
796
797
798
799 public boolean availableDate(final MoneyWiseSecurity pSecurity,
800 final OceanusDate pDate) {
801
802 final Map<OceanusDate, Integer> myMap = theMapOfMaps.get(pSecurity);
803 return myMap == null
804 || myMap.get(pDate) == null;
805 }
806
807
808
809
810
811
812
813
814 public OceanusPrice getPriceForDate(final MoneyWiseAssetBase pSecurity,
815 final OceanusDate pDate) {
816
817 final MoneyWiseSecurity mySecurity = MoneyWiseSecurity.class.cast(pSecurity);
818
819
820 final MoneyWiseSecurityPriceList myList = theMapOfPrices.get(mySecurity);
821 if (myList != null) {
822
823 final Iterator<MoneyWiseSecurityPrice> myIterator = myList.iterator();
824 while (myIterator.hasNext()) {
825 final MoneyWiseSecurityPrice myCurr = myIterator.next();
826
827
828 if (pDate.compareTo(myCurr.getDate()) >= 0) {
829 return myCurr.getPrice();
830 }
831 }
832 }
833
834
835 final Currency myCurrency = mySecurity.getCurrency();
836 return OceanusPrice.getWholeUnits(PrometheusDataInstanceMap.ONE, myCurrency);
837 }
838
839
840
841
842
843
844
845
846 public OceanusPrice[] getPricesForRange(final MoneyWiseSecurity pSecurity,
847 final OceanusDateRange pRange) {
848
849 final Currency myCurrency = pSecurity.getCurrency();
850 OceanusPrice myFirst = OceanusPrice.getWholeUnits(PrometheusDataInstanceMap.ONE, myCurrency);
851 OceanusPrice myLatest = myFirst;
852 final OceanusDate myStart = pRange.getStart();
853
854
855 final MoneyWiseSecurityPriceList myList = theMapOfPrices.get(pSecurity);
856 if (myList != null) {
857
858 final ListIterator<MoneyWiseSecurityPrice> myIterator = myList.listIterator(myList.size());
859 while (myIterator.hasPrevious()) {
860 final MoneyWiseSecurityPrice myCurr = myIterator.previous();
861
862
863 final OceanusDate myDate = myCurr.getDate();
864 final int iComp = pRange.compareToDate(myDate);
865
866
867 if (iComp < 0) {
868 break;
869 }
870
871
872 myLatest = myCurr.getPrice();
873
874
875 if (iComp > 0
876 || myDate.compareTo(myStart) == 0) {
877 myFirst = myLatest;
878 }
879 }
880 }
881
882
883 return new OceanusPrice[]
884 {myFirst, myLatest};
885 }
886
887
888
889
890
891
892
893 public ListIterator<MoneyWiseSecurityPrice> priceIterator(final MoneyWiseSecurity pSecurity) {
894
895 final MoneyWiseSecurityPriceList myList = theMapOfPrices.get(pSecurity);
896 return myList != null
897 ? myList.listIterator(myList.size())
898 : null;
899 }
900
901
902
903
904 private static final class MoneyWiseSecurityPriceList
905 implements MetisFieldItem, MetisDataList<MoneyWiseSecurityPrice> {
906
907
908
909 private static final MetisFieldSet<MoneyWiseSecurityPriceList> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseSecurityPriceList.class);
910
911
912
913
914 static {
915 FIELD_DEFS.declareLocalField(MetisDataResource.LIST_SIZE, MoneyWiseSecurityPriceList::size);
916 }
917
918
919
920
921 private final List<MoneyWiseSecurityPrice> theList;
922
923
924
925
926 private final MoneyWiseSecurity theSecurity;
927
928
929
930
931
932
933 private MoneyWiseSecurityPriceList(final MoneyWiseSecurity pSecurity) {
934 theSecurity = pSecurity;
935 theList = new ArrayList<>();
936 }
937
938 @Override
939 public MetisFieldSet<MoneyWiseSecurityPriceList> getDataFieldSet() {
940 return FIELD_DEFS;
941 }
942
943 @Override
944 public String formatObject(final OceanusDataFormatter pFormatter) {
945 return theSecurity.formatObject(pFormatter)
946 + "("
947 + size()
948 + ")";
949 }
950
951 @Override
952 public String toString() {
953 return theSecurity.toString()
954 + "("
955 + size()
956 + ")";
957 }
958
959 @Override
960 public List<MoneyWiseSecurityPrice> getUnderlyingList() {
961 return theList;
962 }
963 }
964 }
965 }