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.moneywise.data.basic.MoneyWiseSecurity.MoneyWiseSecurityList;
26 import io.github.tonywasher.joceanus.moneywise.exc.MoneyWiseDataException;
27 import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
28 import io.github.tonywasher.joceanus.oceanus.date.OceanusDate;
29 import io.github.tonywasher.joceanus.oceanus.date.OceanusDateFormatter;
30 import io.github.tonywasher.joceanus.oceanus.date.OceanusDateRange;
31 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusPrice;
32 import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
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 myPrice)) {
460 return false;
461 }
462
463
464 pushHistory();
465
466
467 if (!MetisDataDifference.isEqual(getPrice(), myPrice.getPrice())) {
468 setValuePrice(myPrice.getPriceField());
469 }
470
471
472 if (!MetisDataDifference.isEqual(getDate(), myPrice.getDate())) {
473 setValueDate(myPrice.getDate());
474 }
475
476
477 return checkForHistory();
478 }
479
480 @Override
481 public void adjustMapForItem() {
482 final MoneyWiseSecurityPriceBaseList<? extends MoneyWiseSecurityPrice> myList = getList();
483 final MoneyWiseSecurityPriceDataMap myMap = myList.getDataMap();
484 myMap.adjustForItem(this);
485 }
486
487
488
489
490
491
492 public abstract static class MoneyWiseSecurityPriceBaseList<T extends MoneyWiseSecurityPrice>
493 extends PrometheusEncryptedList<T> {
494
495
496
497 static {
498 MetisFieldSet.newFieldSet(MoneyWiseSecurityPriceBaseList.class);
499 }
500
501
502
503
504
505
506
507
508 protected MoneyWiseSecurityPriceBaseList(final MoneyWiseDataSet pData,
509 final Class<T> pClass,
510 final MoneyWiseBasicDataType pItemType) {
511
512 super(pClass, pData, pItemType, PrometheusListStyle.CORE);
513 }
514
515
516
517
518
519
520 protected MoneyWiseSecurityPriceBaseList(final MoneyWiseSecurityPriceBaseList<T> pSource) {
521
522 super(pSource);
523 }
524
525 @Override
526 public MoneyWiseSecurityPriceDataMap getDataMap() {
527 return (MoneyWiseSecurityPriceDataMap) super.getDataMap();
528 }
529
530 @Override
531 protected MoneyWiseSecurityPriceDataMap allocateDataMap() {
532 return new MoneyWiseSecurityPriceDataMap();
533 }
534 }
535
536
537
538
539 public static class MoneyWiseSecurityPriceList
540 extends MoneyWiseSecurityPriceBaseList<MoneyWiseSecurityPrice> {
541
542
543
544 private static final MetisFieldSet<MoneyWiseSecurityPriceList> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseSecurityPriceList.class);
545
546
547
548
549
550
551 protected MoneyWiseSecurityPriceList(final MoneyWiseDataSet pData) {
552 super(pData, MoneyWiseSecurityPrice.class, MoneyWiseBasicDataType.SECURITYPRICE);
553 }
554
555
556
557
558
559
560 private MoneyWiseSecurityPriceList(final MoneyWiseSecurityPriceList pSource) {
561 super(pSource);
562 }
563
564 @Override
565 public MetisFieldSet<MoneyWiseSecurityPriceList> getDataFieldSet() {
566 return FIELD_DEFS;
567 }
568
569 @Override
570 public String listName() {
571 return LIST_NAME;
572 }
573
574 @Override
575 public MetisFieldSetDef getItemFields() {
576 return MoneyWiseSecurityPrice.FIELD_DEFS;
577 }
578
579 @Override
580 public MoneyWiseDataSet getDataSet() {
581 return (MoneyWiseDataSet) super.getDataSet();
582 }
583
584 @Override
585 protected MoneyWiseSecurityPriceList getEmptyList(final PrometheusListStyle pStyle) {
586 final MoneyWiseSecurityPriceList myList = new MoneyWiseSecurityPriceList(this);
587 myList.setStyle(pStyle);
588 return myList;
589 }
590
591
592
593
594
595
596
597
598 public MoneyWiseSecurityPriceList deriveEditList(final PrometheusEditSet pEditSet) throws OceanusException {
599
600 final MoneyWiseSecurityPriceList myList = getEmptyList(PrometheusListStyle.EDIT);
601 myList.ensureMap();
602 pEditSet.setEditEntryList(MoneyWiseBasicDataType.SECURITYPRICE, myList);
603
604
605 final Iterator<MoneyWiseSecurityPrice> myIterator = iterator();
606 while (myIterator.hasNext()) {
607 final MoneyWiseSecurityPrice myCurr = myIterator.next();
608
609
610 final MoneyWiseSecurityPrice myItem = new MoneyWiseSecurityPrice(myList, myCurr);
611 myItem.resolveEditSetLinks(pEditSet);
612 myList.add(myItem);
613
614
615 myItem.adjustMapForItem();
616 }
617
618
619 return myList;
620 }
621
622
623
624
625
626
627
628 @Override
629 public MoneyWiseSecurityPrice addCopyItem(final PrometheusDataItem pPrice) {
630 if (pPrice instanceof MoneyWiseSecurityPrice p) {
631 final MoneyWiseSecurityPrice myPrice = new MoneyWiseSecurityPrice(this, p);
632 add(myPrice);
633 return myPrice;
634 } else {
635 throw new UnsupportedOperationException();
636 }
637 }
638
639
640
641
642
643
644 @Override
645 public MoneyWiseSecurityPrice addNewItem() {
646 final MoneyWiseSecurityPrice myPrice = new MoneyWiseSecurityPrice(this);
647 add(myPrice);
648 return myPrice;
649 }
650
651 @Override
652 public MoneyWiseSecurityPrice addValuesItem(final PrometheusDataValues pValues) throws OceanusException {
653
654 final MoneyWiseSecurityPrice myPrice = new MoneyWiseSecurityPrice(this, pValues);
655
656
657 if (!isIdUnique(myPrice.getIndexedId())) {
658 myPrice.addError(ERROR_DUPLICATE, MetisDataResource.DATA_ID);
659 throw new MoneyWiseDataException(myPrice, ERROR_VALIDATION);
660 }
661
662
663 add(myPrice);
664
665
666 return myPrice;
667 }
668 }
669
670
671
672
673 public static class MoneyWiseSecurityPriceDataMap
674 implements PrometheusDataMapItem, MetisFieldItem {
675
676
677
678 @SuppressWarnings("rawtypes")
679 private static final MetisFieldSet<MoneyWiseSecurityPriceDataMap> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseSecurityPriceDataMap.class);
680
681
682
683
684 static {
685 FIELD_DEFS.declareLocalField(MoneyWiseBasicResource.MONEYWISEDATA_MAP_MAPOFMAPS, MoneyWiseSecurityPriceDataMap::getMapOfMaps);
686 FIELD_DEFS.declareLocalField(MoneyWiseBasicResource.SECURITYPRICE_MAP_MAPOFPRICES, MoneyWiseSecurityPriceDataMap::getMapOfPrices);
687 }
688
689
690
691
692 private final Map<MoneyWiseSecurity, Map<OceanusDate, Integer>> theMapOfMaps;
693
694
695
696
697 private final Map<MoneyWiseSecurity, MoneyWiseSecurityPriceList> theMapOfPrices;
698
699
700
701
702 public MoneyWiseSecurityPriceDataMap() {
703
704 theMapOfMaps = new HashMap<>();
705 theMapOfPrices = new HashMap<>();
706 }
707
708 @SuppressWarnings("rawtypes")
709 @Override
710 public MetisFieldSet<MoneyWiseSecurityPriceDataMap> getDataFieldSet() {
711 return FIELD_DEFS;
712 }
713
714 @Override
715 public String formatObject(final OceanusDataFormatter pFormatter) {
716 return FIELD_DEFS.getName();
717 }
718
719
720
721
722
723
724 private Map<MoneyWiseSecurity, Map<OceanusDate, Integer>> getMapOfMaps() {
725 return theMapOfMaps;
726 }
727
728
729
730
731
732
733 private Map<MoneyWiseSecurity, MoneyWiseSecurityPriceList> getMapOfPrices() {
734 return theMapOfPrices;
735 }
736
737 @Override
738 public void resetMap() {
739 theMapOfMaps.clear();
740 theMapOfPrices.clear();
741 }
742
743 @Override
744 public void adjustForItem(final PrometheusDataItem pItem) {
745
746 final MoneyWiseSecurityPrice myItem = (MoneyWiseSecurityPrice) pItem;
747 final MoneyWiseSecurity mySecurity = myItem.getSecurity();
748 if (mySecurity == null) {
749 return;
750 }
751
752
753 final Map<OceanusDate, Integer> myMap = theMapOfMaps.computeIfAbsent(mySecurity, s -> new HashMap<>());
754
755
756 final OceanusDate myDate = myItem.getDate();
757 final Integer myCount = myMap.get(myDate);
758 if (myCount == null) {
759 myMap.put(myDate, PrometheusDataInstanceMap.ONE);
760 } else {
761 myMap.put(myDate, myCount + 1);
762 }
763
764
765 final MoneyWiseSecurityPriceList myList = theMapOfPrices.computeIfAbsent(mySecurity, MoneyWiseSecurityPriceList::new);
766
767
768 myList.add(myItem);
769 }
770
771
772
773
774
775
776
777 public boolean validPriceCount(final MoneyWiseSecurityPrice pItem) {
778
779 final MoneyWiseSecurity mySecurity = pItem.getSecurity();
780 final OceanusDate myDate = pItem.getDate();
781
782
783 final Map<OceanusDate, Integer> myMap = theMapOfMaps.get(mySecurity);
784 if (myMap != null) {
785 final Integer myResult = myMap.get(myDate);
786 return PrometheusDataInstanceMap.ONE.equals(myResult);
787 }
788 return false;
789 }
790
791
792
793
794
795
796
797
798 public boolean availableDate(final MoneyWiseSecurity pSecurity,
799 final OceanusDate pDate) {
800
801 final Map<OceanusDate, Integer> myMap = theMapOfMaps.get(pSecurity);
802 return myMap == null
803 || myMap.get(pDate) == null;
804 }
805
806
807
808
809
810
811
812
813 public OceanusPrice getPriceForDate(final MoneyWiseAssetBase pSecurity,
814 final OceanusDate pDate) {
815
816 final MoneyWiseSecurity mySecurity = MoneyWiseSecurity.class.cast(pSecurity);
817
818
819 final MoneyWiseSecurityPriceList myList = theMapOfPrices.get(mySecurity);
820 if (myList != null) {
821
822 final Iterator<MoneyWiseSecurityPrice> myIterator = myList.iterator();
823 while (myIterator.hasNext()) {
824 final MoneyWiseSecurityPrice myCurr = myIterator.next();
825
826
827 if (pDate.compareTo(myCurr.getDate()) >= 0) {
828 return myCurr.getPrice();
829 }
830 }
831 }
832
833
834 final Currency myCurrency = mySecurity.getCurrency();
835 return OceanusPrice.getWholeUnits(PrometheusDataInstanceMap.ONE, myCurrency);
836 }
837
838
839
840
841
842
843
844
845 public OceanusPrice[] getPricesForRange(final MoneyWiseSecurity pSecurity,
846 final OceanusDateRange pRange) {
847
848 final Currency myCurrency = pSecurity.getCurrency();
849 OceanusPrice myFirst = OceanusPrice.getWholeUnits(PrometheusDataInstanceMap.ONE, myCurrency);
850 OceanusPrice myLatest = myFirst;
851 final OceanusDate myStart = pRange.getStart();
852
853
854 final MoneyWiseSecurityPriceList myList = theMapOfPrices.get(pSecurity);
855 if (myList != null) {
856
857 final ListIterator<MoneyWiseSecurityPrice> myIterator = myList.listIterator(myList.size());
858 while (myIterator.hasPrevious()) {
859 final MoneyWiseSecurityPrice myCurr = myIterator.previous();
860
861
862 final OceanusDate myDate = myCurr.getDate();
863 final int iComp = pRange.compareToDate(myDate);
864
865
866 if (iComp < 0) {
867 break;
868 }
869
870
871 myLatest = myCurr.getPrice();
872
873
874 if (iComp > 0
875 || myDate.compareTo(myStart) == 0) {
876 myFirst = myLatest;
877 }
878 }
879 }
880
881
882 return new OceanusPrice[]
883 {myFirst, myLatest};
884 }
885
886
887
888
889
890
891
892 public ListIterator<MoneyWiseSecurityPrice> priceIterator(final MoneyWiseSecurity pSecurity) {
893
894 final MoneyWiseSecurityPriceList myList = theMapOfPrices.get(pSecurity);
895 return myList != null
896 ? myList.listIterator(myList.size())
897 : null;
898 }
899
900
901
902
903 private static final class MoneyWiseSecurityPriceList
904 implements MetisFieldItem, MetisDataList<MoneyWiseSecurityPrice> {
905
906
907
908 private static final MetisFieldSet<MoneyWiseSecurityPriceList> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseSecurityPriceList.class);
909
910
911
912
913 static {
914 FIELD_DEFS.declareLocalField(MetisDataResource.LIST_SIZE, MoneyWiseSecurityPriceList::size);
915 }
916
917
918
919
920 private final List<MoneyWiseSecurityPrice> theList;
921
922
923
924
925 private final MoneyWiseSecurity theSecurity;
926
927
928
929
930
931
932 private MoneyWiseSecurityPriceList(final MoneyWiseSecurity pSecurity) {
933 theSecurity = pSecurity;
934 theList = new ArrayList<>();
935 }
936
937 @Override
938 public MetisFieldSet<MoneyWiseSecurityPriceList> getDataFieldSet() {
939 return FIELD_DEFS;
940 }
941
942 @Override
943 public String formatObject(final OceanusDataFormatter pFormatter) {
944 return theSecurity.formatObject(pFormatter)
945 + "("
946 + size()
947 + ")";
948 }
949
950 @Override
951 public String toString() {
952 return theSecurity.toString()
953 + "("
954 + size()
955 + ")";
956 }
957
958 @Override
959 public List<MoneyWiseSecurityPrice> getUnderlyingList() {
960 return theList;
961 }
962 }
963 }
964 }