1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.prometheus.data;
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.decimal.OceanusDecimalParser;
23 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
24 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusPrice;
25 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusRate;
26 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusRatio;
27 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusUnits;
28 import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
29 import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
30 import io.github.tonywasher.joceanus.metis.list.MetisListKey;
31 import io.github.tonywasher.joceanus.prometheus.exc.PrometheusDataException;
32 import io.github.tonywasher.joceanus.prometheus.exc.PrometheusLogicException;
33
34 import java.util.Date;
35
36
37
38
39
40
41 public abstract class PrometheusDataInfoItem
42 extends PrometheusEncryptedDataItem {
43
44
45
46 public static final int DATALEN = 512;
47
48
49
50
51 private static final PrometheusEncryptedFieldSet<PrometheusDataInfoItem> FIELD_DEFS = PrometheusEncryptedFieldSet.newEncryptedFieldSet(PrometheusDataInfoItem.class);
52
53
54
55
56 static {
57 FIELD_DEFS.declareLinkField(PrometheusDataResource.DATAINFO_TYPE);
58 FIELD_DEFS.declareLinkField(PrometheusDataResource.DATAINFO_OWNER);
59 FIELD_DEFS.declareEncryptedContextField(PrometheusDataResource.DATAINFO_VALUE);
60 FIELD_DEFS.declareDerivedVersionedField(PrometheusDataResource.DATAINFO_LINK);
61 }
62
63
64
65
66 protected static final String ERROR_BADDATATYPE = PrometheusDataResource.DATAINFO_ERROR_TYPE.getValue();
67
68
69
70
71 protected static final String ERROR_BADDATA = PrometheusDataResource.DATAINFO_ERROR_DATA.getValue();
72
73
74
75
76 protected static final String ERROR_BADINFOCLASS = PrometheusDataResource.DATAINFO_ERROR_CLASS.getValue();
77
78
79
80
81
82
83
84 protected PrometheusDataInfoItem(final PrometheusDataInfoList<?> pList,
85 final PrometheusDataInfoItem pInfo) {
86
87 super(pList, pInfo);
88 }
89
90
91
92
93
94
95 protected PrometheusDataInfoItem(final PrometheusDataInfoList<?> pList) {
96
97 super(pList, 0);
98 }
99
100
101
102
103
104
105
106
107
108
109
110 protected PrometheusDataInfoItem(final PrometheusDataInfoList<?> pList,
111 final Integer uId,
112 final Integer uKeySetId,
113 final Integer uInfoTypeId,
114 final Integer uOwnerId) throws OceanusException {
115
116 super(pList, uId);
117
118
119 setValueInfoType(uInfoTypeId);
120 setValueOwner(uOwnerId);
121
122
123 setDataKeySet(uKeySetId);
124 }
125
126
127
128
129
130
131
132
133
134 protected PrometheusDataInfoItem(final PrometheusDataInfoList<?> pList,
135 final Integer uId,
136 final PrometheusStaticDataItem pInfoType,
137 final PrometheusDataItem pOwner) {
138
139 super(pList, uId);
140
141
142 setValueInfoType(pInfoType);
143 setValueOwner(pOwner);
144 }
145
146
147
148
149
150
151
152
153 protected PrometheusDataInfoItem(final PrometheusDataInfoList<?> pList,
154 final PrometheusDataValues pValues) throws OceanusException {
155
156 super(pList, pValues);
157
158
159 Object myValue = pValues.getValue(PrometheusDataResource.DATAINFO_TYPE);
160 if (myValue instanceof Integer i) {
161 setValueInfoType(i);
162 } else if (myValue instanceof String s) {
163 setValueInfoType(s);
164 } else if (myValue instanceof PrometheusStaticDataItem myStatic) {
165 setValueInfoType(myStatic);
166 }
167
168
169 myValue = pValues.getValue(PrometheusDataResource.DATAINFO_OWNER);
170 if (myValue instanceof Integer i) {
171 setValueOwner(i);
172 } else if (myValue instanceof String s) {
173 setValueOwner(s);
174 } else if (myValue instanceof PrometheusDataItem myItem) {
175 setValueOwner(myItem);
176 }
177 }
178
179 @Override
180 public String toString() {
181
182 final PrometheusEncryptedValues myValues = getValues();
183 final Object myType = myValues.getValue(PrometheusDataResource.DATAINFO_TYPE, Object.class);
184 if (!(myType instanceof PrometheusStaticDataItem)) {
185 return super.toString();
186 }
187
188
189 final PrometheusStaticDataItem myInfoType = (PrometheusStaticDataItem) myType;
190
191
192 return myInfoType.getName() + "=" + super.toString();
193 }
194
195 @Override
196 public String formatObject(final OceanusDataFormatter pFormatter) {
197
198 final PrometheusEncryptedValues myValues = getValues();
199 final Object myType = myValues.getValue(PrometheusDataResource.DATAINFO_TYPE, Object.class);
200 if (!(myType instanceof PrometheusStaticDataItem)) {
201 return super.formatObject(pFormatter);
202 }
203
204
205 final PrometheusStaticDataItem myInfoType = getInfoType();
206
207
208 final OceanusDataFormatter myFormatter = getDataSet().getDataFormatter();
209 final PrometheusDataInfoClass myInfoClass = (PrometheusDataInfoClass) myInfoType.getStaticClass();
210
211
212 switch (myInfoClass.getDataType()) {
213 case LINK:
214 case LINKPAIR:
215 case LINKSET:
216 return myFormatter.formatObject(getLink());
217 default:
218 return myFormatter.formatObject(getValue(Object.class));
219 }
220 }
221
222
223
224
225
226
227 public abstract PrometheusStaticDataItem getInfoType();
228
229
230
231
232
233
234 public abstract PrometheusDataInfoClass getInfoClass();
235
236
237
238
239
240
241 public Integer getInfoTypeId() {
242 return getInfoType().getIndexedId();
243 }
244
245
246
247
248
249
250 public abstract PrometheusDataItem getOwner();
251
252
253
254
255
256
257 public Integer getOwnerId() {
258 return getOwner().getIndexedId();
259 }
260
261
262
263
264
265
266
267
268 public <X extends PrometheusDataItem> X getLink(final Class<X> pClass) {
269 return getValues().getValue(PrometheusDataResource.DATAINFO_LINK, pClass);
270 }
271
272
273
274
275
276
277 public String getLinkName() {
278 return null;
279 }
280
281
282
283
284
285
286 protected PrometheusDataItem getLink() {
287 return getValues().getValue(PrometheusDataResource.DATAINFO_LINK, PrometheusDataItem.class);
288 }
289
290
291
292
293
294
295
296
297 public <X> X getValue(final Class<X> pClass) {
298 return getValues().getValue(PrometheusDataResource.DATAINFO_VALUE, pClass);
299 }
300
301
302
303
304
305
306 public PrometheusEncryptedPair getField() {
307 return getField(getValues());
308 }
309
310
311
312
313
314
315 public byte[] getValueBytes() {
316 return getValues().getEncryptedBytes(PrometheusDataResource.DATAINFO_VALUE);
317 }
318
319
320
321
322
323
324
325
326
327 public static <X> X getValue(final PrometheusEncryptedValues pValueSet,
328 final Class<X> pClass) {
329 return pValueSet.isDeletion()
330 ? null
331 : pValueSet.getValue(PrometheusDataResource.DATAINFO_VALUE, pClass);
332 }
333
334
335
336
337
338
339
340 public static PrometheusEncryptedPair getField(final PrometheusEncryptedValues pValueSet) {
341 return pValueSet.isDeletion()
342 ? null
343 : pValueSet.getEncryptedPair(PrometheusDataResource.DATAINFO_VALUE);
344 }
345
346
347
348
349
350
351
352 protected final void setValueInfoType(final PrometheusStaticDataItem pValue) {
353 getValues().setUncheckedValue(PrometheusDataResource.DATAINFO_TYPE, pValue);
354 }
355
356
357
358
359
360
361 protected final void setValueInfoType(final Integer pId) {
362 getValues().setUncheckedValue(PrometheusDataResource.DATAINFO_TYPE, pId);
363 }
364
365
366
367
368
369
370 protected final void setValueInfoType(final String pName) {
371 getValues().setUncheckedValue(PrometheusDataResource.DATAINFO_TYPE, pName);
372 }
373
374
375
376
377
378
379 protected final void setValueOwner(final PrometheusDataItem pValue) {
380 getValues().setUncheckedValue(PrometheusDataResource.DATAINFO_OWNER, pValue);
381 }
382
383
384
385
386
387
388 protected final void setValueOwner(final Integer pId) {
389 getValues().setUncheckedValue(PrometheusDataResource.DATAINFO_OWNER, pId);
390 }
391
392
393
394
395
396
397 protected final void setValueOwner(final String pName) {
398 getValues().setUncheckedValue(PrometheusDataResource.DATAINFO_OWNER, pName);
399 }
400
401
402
403
404
405
406
407 protected void setValueValue(final Object pValue) throws OceanusException {
408 getValues().setDeletion(false);
409 setEncryptedValue(PrometheusDataResource.DATAINFO_VALUE, pValue);
410 }
411
412
413
414
415
416
417 protected void setValueValue(final PrometheusEncryptedPair pValue) {
418 final PrometheusEncryptedValues myValues = getValues();
419 myValues.setDeletion(false);
420 myValues.setUncheckedValue(PrometheusDataResource.DATAINFO_VALUE, pValue);
421 }
422
423
424
425
426
427
428
429
430
431 protected <X> void setValueBytes(final byte[] pBytes,
432 final Class<X> pClass) throws OceanusException {
433 setEncryptedValue(PrometheusDataResource.DATAINFO_VALUE, pBytes, pClass);
434 }
435
436
437
438
439
440
441 protected void setValueLink(final PrometheusDataItem pLink) {
442 final PrometheusEncryptedValues myValues = getValues();
443 myValues.setDeletion(false);
444 myValues.setUncheckedValue(PrometheusDataResource.DATAINFO_LINK, pLink);
445 }
446
447
448
449
450
451
452 private void setValueLink(final Integer pId) {
453 final PrometheusEncryptedValues myValues = getValues();
454 myValues.setUncheckedValue(PrometheusDataResource.DATAINFO_LINK, pId);
455 }
456
457
458
459
460
461
462 private void setValueLink(final Long pId) {
463 final PrometheusEncryptedValues myValues = getValues();
464 myValues.setUncheckedValue(PrometheusDataResource.DATAINFO_LINK, pId);
465 }
466
467
468
469
470
471
472 protected void setValueLink(final String pName) {
473 final PrometheusEncryptedValues myValues = getValues();
474 myValues.setUncheckedValue(PrometheusDataResource.DATAINFO_LINK, pName);
475 }
476
477
478
479
480 public void markDeleted() {
481
482 getValues().setDeletion(true);
483 }
484
485 @Override
486 public void touchUnderlyingItems() {
487
488 super.touchUnderlyingItems();
489
490
491 getInfoType().touchItem(this);
492 }
493
494
495
496
497
498
499
500 protected void setValue(final Object pValue) throws OceanusException {
501
502 final PrometheusStaticDataItem myType = getInfoType();
503 final PrometheusDataInfoClass myClass = (PrometheusDataInfoClass) myType.getStaticClass();
504
505
506 final PrometheusDataSet myDataSet = getDataSet();
507 final OceanusDataFormatter myFormatter = myDataSet.getDataFormatter();
508 final OceanusDecimalParser myParser = myFormatter.getDecimalParser();
509
510
511 boolean bValueOK = false;
512 switch (myClass.getDataType()) {
513 case DATE:
514 bValueOK = setDateValue(myFormatter.getDateFormatter(), pValue);
515 break;
516 case INTEGER:
517 bValueOK = setIntegerValue(myFormatter, pValue);
518 break;
519 case LINK:
520 case LINKSET:
521 bValueOK = setLinkValue(pValue);
522 break;
523 case LINKPAIR:
524 bValueOK = setLinkPairValue(pValue);
525 break;
526 case STRING:
527 bValueOK = setStringValue(pValue);
528 break;
529 case CHARARRAY:
530 bValueOK = setCharArrayValue(pValue);
531 break;
532 case MONEY:
533 bValueOK = setMoneyValue(myParser, pValue);
534 break;
535 case RATE:
536 bValueOK = setRateValue(myParser, pValue);
537 break;
538 case UNITS:
539 bValueOK = setUnitsValue(myParser, pValue);
540 break;
541 case PRICE:
542 bValueOK = setPriceValue(myParser, pValue);
543 break;
544 case RATIO:
545 bValueOK = setRatioValue(myParser, pValue);
546 break;
547 default:
548 break;
549 }
550
551
552 if (!bValueOK) {
553 throw new PrometheusLogicException(this, ERROR_BADDATATYPE);
554 }
555 }
556
557
558
559
560
561
562
563
564
565 private boolean setDateValue(final OceanusDateFormatter pFormatter,
566 final Object pValue) throws OceanusException {
567 try {
568
569 if (pValue instanceof Date d) {
570 setValueValue(new OceanusDate(d));
571 return true;
572 } else if (pValue instanceof OceanusDate) {
573 setValueValue(pValue);
574 return true;
575 } else if (pValue instanceof byte[] ba) {
576 setValueBytes(ba, OceanusDate.class);
577 return true;
578 } else if (pValue instanceof String s) {
579 setValueValue(pFormatter.parseDate(s));
580 return true;
581 }
582 } catch (IllegalArgumentException e) {
583 throw new PrometheusDataException(pValue, ERROR_BADDATA, e);
584 }
585 return false;
586 }
587
588
589
590
591
592
593
594
595
596 private boolean setIntegerValue(final OceanusDataFormatter pFormatter,
597 final Object pValue) throws OceanusException {
598 try {
599
600 if (pValue instanceof Integer) {
601 setValueValue(pValue);
602 return true;
603 } else if (pValue instanceof byte[] ba) {
604 setValueBytes(ba, Integer.class);
605 return true;
606 } else if (pValue instanceof String s) {
607 setValueValue(pFormatter.parseValue(s, Integer.class));
608 return true;
609 }
610 } catch (IllegalArgumentException e) {
611 throw new PrometheusDataException(pValue, ERROR_BADDATA, e);
612 }
613 return false;
614 }
615
616
617
618
619
620
621
622
623 private boolean setLinkValue(final Object pValue) throws OceanusException {
624 try {
625
626 if (pValue instanceof Integer i) {
627 setValueValue(pValue);
628 setValueLink(i);
629 return true;
630 } else if (pValue instanceof byte[] ba) {
631 setValueBytes(ba, Integer.class);
632 setValueLink(getValue(Integer.class));
633 return true;
634 } else if (pValue instanceof String s) {
635 setValueLink(s);
636 return true;
637 } else if (pValue instanceof PrometheusDataItem myItem) {
638 setValueValue(myItem.getIndexedId());
639 setValueLink(myItem);
640 return true;
641 }
642 } catch (IllegalArgumentException e) {
643 throw new PrometheusDataException(pValue, ERROR_BADDATA, e);
644 }
645 return false;
646 }
647
648
649
650
651
652
653
654
655 private boolean setLinkPairValue(final Object pValue) throws OceanusException {
656 try {
657
658 if (pValue instanceof Long l) {
659 setValueValue(pValue);
660 setValueLink(l);
661 return true;
662 } else if (pValue instanceof byte[] ba) {
663 setValueBytes(ba, Long.class);
664 setValueLink(getValue(Long.class));
665 return true;
666 } else if (pValue instanceof String s) {
667 setValueLink(s);
668 return true;
669 } else if (pValue instanceof PrometheusDataItem myItem) {
670 setValueValue(myItem.getIndexedId());
671 setValueLink(myItem);
672 return true;
673 }
674 } catch (IllegalArgumentException e) {
675 throw new PrometheusDataException(pValue, ERROR_BADDATA, e);
676 }
677 return false;
678 }
679
680
681
682
683
684
685
686
687 private boolean setStringValue(final Object pValue) throws OceanusException {
688
689 if (pValue instanceof String) {
690 setValueValue(pValue);
691 return true;
692 } else if (pValue instanceof byte[] ba) {
693 setValueBytes(ba, String.class);
694 return true;
695 }
696 return false;
697 }
698
699
700
701
702
703
704
705
706 private boolean setCharArrayValue(final Object pValue) throws OceanusException {
707
708 if (pValue instanceof char[]) {
709 setValueValue(pValue);
710 return true;
711 } else if (pValue instanceof byte[] ba) {
712 setValueBytes(ba, char[].class);
713 return true;
714 } else if (pValue instanceof String s) {
715 setValueValue(s.toCharArray());
716 return true;
717 }
718 return false;
719 }
720
721
722
723
724
725
726
727
728
729 private boolean setMoneyValue(final OceanusDecimalParser pParser,
730 final Object pValue) throws OceanusException {
731
732 if (pValue instanceof OceanusMoney) {
733 setValueValue(pValue);
734 return true;
735 } else if (pValue instanceof byte[] ba) {
736 setValueBytes(ba, OceanusMoney.class);
737 return true;
738 } else if (pValue instanceof String s) {
739 setValueValue(pParser.parseMoneyValue(s));
740 return true;
741 }
742 return false;
743 }
744
745
746
747
748
749
750
751
752
753 private boolean setRateValue(final OceanusDecimalParser pParser,
754 final Object pValue) throws OceanusException {
755
756 if (pValue instanceof OceanusRate) {
757 setValueValue(pValue);
758 return true;
759 } else if (pValue instanceof byte[] ba) {
760 setValueBytes(ba, OceanusRate.class);
761 return true;
762 } else if (pValue instanceof String s) {
763 setValueValue(pParser.parseRateValue(s));
764 return true;
765 }
766 return false;
767 }
768
769
770
771
772
773
774
775
776
777 private boolean setRatioValue(final OceanusDecimalParser pParser,
778 final Object pValue) throws OceanusException {
779
780 if (pValue instanceof OceanusRatio) {
781 setValueValue(pValue);
782 return true;
783 } else if (pValue instanceof byte[] ba) {
784 setValueBytes(ba, OceanusRatio.class);
785 return true;
786 } else if (pValue instanceof String s) {
787 setValueValue(pParser.parseRatioValue(s));
788 return true;
789 }
790 return false;
791 }
792
793
794
795
796
797
798
799
800
801 private boolean setUnitsValue(final OceanusDecimalParser pParser,
802 final Object pValue) throws OceanusException {
803
804 if (pValue instanceof OceanusUnits) {
805 setValueValue(pValue);
806 return true;
807 } else if (pValue instanceof byte[] ba) {
808 setValueBytes(ba, OceanusUnits.class);
809 return true;
810 } else if (pValue instanceof String s) {
811 setValueValue(pParser.parseUnitsValue(s));
812 return true;
813 }
814 return false;
815 }
816
817
818
819
820
821
822
823
824
825 private boolean setPriceValue(final OceanusDecimalParser pParser,
826 final Object pValue) throws OceanusException {
827
828 if (pValue instanceof OceanusPrice) {
829 setValueValue(pValue);
830 return true;
831 } else if (pValue instanceof byte[] ba) {
832 setValueBytes(ba, OceanusPrice.class);
833 return true;
834 } else if (pValue instanceof String s) {
835 setValueValue(pParser.parsePriceValue(s));
836 return true;
837 }
838 return false;
839 }
840
841 @Override
842 public void rewindToVersion(final int pVersion) {
843
844 super.rewindToVersion(pVersion);
845
846
847 if (getInfoClass().isLinkSet()) {
848
849 rewindInfoLinkSet();
850 }
851 }
852
853
854
855
856 public void rewindInfoLinkSet() {
857 }
858
859 @Override
860 public int compareValues(final PrometheusDataItem pThat) {
861
862 final PrometheusDataInfoItem myThat = (PrometheusDataInfoItem) pThat;
863 int iDiff = getOwner().compareTo(myThat.getOwner());
864 if (iDiff == 0) {
865 iDiff = getInfoType().compareTo(myThat.getInfoType());
866 }
867 return iDiff;
868 }
869
870
871
872
873
874
875 public abstract static class PrometheusDataInfoList<T extends PrometheusDataInfoItem>
876 extends PrometheusEncryptedList<T> {
877
878
879
880 static {
881 MetisFieldSet.newFieldSet(PrometheusDataInfoList.class);
882 }
883
884
885
886
887
888
889
890
891
892 protected PrometheusDataInfoList(final Class<T> pBaseClass,
893 final PrometheusDataSet pData,
894 final MetisListKey pItemType,
895 final PrometheusListStyle pStyle) {
896 super(pBaseClass, pData, pItemType, pStyle);
897 }
898
899
900
901
902
903
904 protected PrometheusDataInfoList(final PrometheusDataInfoList<T> pSource) {
905 super(pSource);
906 }
907
908 @Override
909 public boolean includeDataXML() {
910 return false;
911 }
912
913 @Override
914 protected abstract PrometheusDataInfoList<T> getEmptyList(PrometheusListStyle pStyle);
915
916
917
918
919
920
921
922
923 protected abstract T addNewItem(PrometheusDataItem pOwner,
924 PrometheusStaticDataItem pInfoType);
925
926
927
928
929
930
931
932
933
934
935 public abstract void addInfoItem(Integer pId,
936 PrometheusDataItem pOwner,
937 PrometheusDataInfoClass pInfoClass,
938 Object pValue) throws OceanusException;
939
940 @Override
941 public void updateMaps() {
942
943 }
944
945 @Override
946 protected PrometheusDataMapItem allocateDataMap() {
947
948 throw new UnsupportedOperationException();
949 }
950 }
951 }