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.format.OceanusDataFormatter;
21 import io.github.tonywasher.joceanus.metis.data.MetisDataDifference;
22 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
23 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataNamedItem;
24 import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
25 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseDataValidator.MoneyWiseDataValidatorParentDefaults;
26 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCategoryInterface;
27 import io.github.tonywasher.joceanus.moneywise.exc.MoneyWiseDataException;
28 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataInstanceMap;
29 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataItem;
30 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataResource;
31 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataValues;
32 import io.github.tonywasher.joceanus.prometheus.data.PrometheusEncryptedDataItem;
33 import io.github.tonywasher.joceanus.prometheus.data.PrometheusEncryptedFieldSet;
34 import io.github.tonywasher.joceanus.prometheus.data.PrometheusEncryptedPair;
35 import io.github.tonywasher.joceanus.prometheus.data.PrometheusStaticDataItem;
36
37 import java.util.Iterator;
38
39
40
41
42 public abstract class MoneyWiseCategoryBase
43 extends PrometheusEncryptedDataItem
44 implements MetisDataNamedItem {
45
46
47
48 public static final String STR_SEP = ":";
49
50
51
52
53 private static final PrometheusEncryptedFieldSet<MoneyWiseCategoryBase> FIELD_DEFS = PrometheusEncryptedFieldSet.newEncryptedFieldSet(MoneyWiseCategoryBase.class);
54
55
56
57
58 static {
59 FIELD_DEFS.declareEncryptedStringField(PrometheusDataResource.DATAITEM_FIELD_NAME, NAMELEN);
60 FIELD_DEFS.declareEncryptedStringField(PrometheusDataResource.DATAITEM_FIELD_DESC, DESCLEN);
61 FIELD_DEFS.declareLinkField(PrometheusDataResource.DATAGROUP_PARENT);
62 FIELD_DEFS.declareDerivedVersionedField(MoneyWiseBasicResource.CATEGORY_SUBCAT);
63 }
64
65
66
67
68
69
70
71 protected MoneyWiseCategoryBase(final MoneyWiseCategoryBaseList<?> pList,
72 final MoneyWiseCategoryBase pCategory) {
73
74 super(pList, pCategory);
75 }
76
77
78
79
80
81
82
83
84 protected MoneyWiseCategoryBase(final MoneyWiseCategoryBaseList<?> pList,
85 final PrometheusDataValues pValues) throws OceanusException {
86
87 super(pList, pValues);
88
89
90 try {
91
92 Object myValue = pValues.getValue(PrometheusDataResource.DATAITEM_FIELD_NAME);
93 if (myValue instanceof String s) {
94 setValueName(s);
95 } else if (myValue instanceof byte[] ba) {
96 setValueName(ba);
97 }
98
99
100 myValue = pValues.getValue(PrometheusDataResource.DATAITEM_FIELD_DESC);
101 if (myValue instanceof String s) {
102 setValueDesc(s);
103 } else if (myValue instanceof byte[] ba) {
104 setValueDesc(ba);
105 }
106
107
108 myValue = pValues.getValue(PrometheusDataResource.DATAGROUP_PARENT);
109 if (myValue instanceof Integer i) {
110 setValueParent(i);
111 } else if (myValue instanceof String s) {
112 setValueParent(s);
113 }
114
115
116 resolveSubCategory();
117
118
119 } catch (OceanusException e) {
120
121 throw new MoneyWiseDataException(this, ERROR_CREATEITEM, e);
122 }
123 }
124
125
126
127
128
129
130 protected MoneyWiseCategoryBase(final MoneyWiseCategoryBaseList<?> pList) {
131 super(pList, 0);
132 setNextDataKeySet();
133 }
134
135 @Override
136 public String formatObject(final OceanusDataFormatter pFormatter) {
137 return toString();
138 }
139
140 @Override
141 public String toString() {
142 return getName();
143 }
144
145 @Override
146 public boolean includeXmlField(final MetisDataFieldId pField) {
147
148 if (PrometheusDataResource.DATAITEM_FIELD_NAME.equals(pField)) {
149 return true;
150 }
151 if (PrometheusDataResource.DATAITEM_FIELD_DESC.equals(pField)) {
152 return getDesc() != null;
153 }
154 if (PrometheusDataResource.DATAGROUP_PARENT.equals(pField)) {
155 return getParentCategory() != null;
156 }
157
158
159 return super.includeXmlField(pField);
160 }
161
162 @Override
163 public String getName() {
164 return getValues().getValue(PrometheusDataResource.DATAITEM_FIELD_NAME, String.class);
165 }
166
167
168
169
170
171
172 public byte[] getNameBytes() {
173 return getValues().getEncryptedBytes(PrometheusDataResource.DATAITEM_FIELD_NAME);
174 }
175
176
177
178
179
180
181 private PrometheusEncryptedPair getNameField() {
182 return getValues().getEncryptedPair(PrometheusDataResource.DATAITEM_FIELD_NAME);
183 }
184
185
186
187
188
189
190 public String getDesc() {
191 return getValues().getValue(PrometheusDataResource.DATAITEM_FIELD_DESC, String.class);
192 }
193
194
195
196
197
198
199 public byte[] getDescBytes() {
200 return getValues().getEncryptedBytes(PrometheusDataResource.DATAITEM_FIELD_DESC);
201 }
202
203
204
205
206
207
208 private PrometheusEncryptedPair getDescField() {
209 return getValues().getEncryptedPair(PrometheusDataResource.DATAITEM_FIELD_DESC);
210 }
211
212
213
214
215
216
217 public abstract PrometheusStaticDataItem getCategoryType();
218
219
220
221
222
223
224 public Integer getCategoryTypeId() {
225 final PrometheusStaticDataItem myType = getCategoryType();
226 return (myType == null)
227 ? null
228 : myType.getIndexedId();
229 }
230
231
232
233
234
235
236 public String getCategoryTypeName() {
237 final PrometheusStaticDataItem myType = getCategoryType();
238 return myType == null
239 ? null
240 : myType.getName();
241 }
242
243
244
245
246
247
248 public abstract MoneyWiseCategoryInterface getCategoryTypeClass();
249
250
251
252
253
254
255 public abstract MoneyWiseCategoryBase getParentCategory();
256
257
258
259
260
261
262 public Integer getParentCategoryId() {
263 final MoneyWiseCategoryBase myParent = getParentCategory();
264 return myParent == null
265 ? null
266 : myParent.getIndexedId();
267 }
268
269
270
271
272
273
274 public String getParentCategoryName() {
275 final MoneyWiseCategoryBase myParent = getParentCategory();
276 return myParent == null
277 ? null
278 : myParent.getName();
279 }
280
281
282
283
284
285
286 public String getSubCategory() {
287 return getValues().getValue(MoneyWiseBasicResource.CATEGORY_SUBCAT, String.class);
288 }
289
290
291
292
293
294
295
296 private void setValueName(final String pValue) throws OceanusException {
297 setEncryptedValue(PrometheusDataResource.DATAITEM_FIELD_NAME, pValue);
298 }
299
300
301
302
303
304
305
306 private void setValueName(final byte[] pBytes) throws OceanusException {
307 setEncryptedValue(PrometheusDataResource.DATAITEM_FIELD_NAME, pBytes, String.class);
308 }
309
310
311
312
313
314
315 private void setValueName(final PrometheusEncryptedPair pValue) {
316 getValues().setUncheckedValue(PrometheusDataResource.DATAITEM_FIELD_NAME, pValue);
317 }
318
319
320
321
322
323
324
325 private void setValueDesc(final String pValue) throws OceanusException {
326 setEncryptedValue(PrometheusDataResource.DATAITEM_FIELD_DESC, pValue);
327 }
328
329
330
331
332
333
334
335 private void setValueDesc(final byte[] pBytes) throws OceanusException {
336 setEncryptedValue(PrometheusDataResource.DATAITEM_FIELD_DESC, pBytes, String.class);
337 }
338
339
340
341
342
343
344 private void setValueDesc(final PrometheusEncryptedPair pValue) {
345 getValues().setUncheckedValue(PrometheusDataResource.DATAITEM_FIELD_DESC, pValue);
346 }
347
348
349
350
351
352
353 private void setValueParent(final MoneyWiseCategoryBase pValue) {
354 getValues().setUncheckedValue(PrometheusDataResource.DATAGROUP_PARENT, pValue);
355 }
356
357
358
359
360
361
362 private void setValueParent(final Integer pValue) {
363 getValues().setUncheckedValue(PrometheusDataResource.DATAGROUP_PARENT, pValue);
364 }
365
366
367
368
369
370
371 private void setValueParent(final String pValue) {
372 getValues().setUncheckedValue(PrometheusDataResource.DATAGROUP_PARENT, pValue);
373 }
374
375
376
377
378
379
380 private void setValueSubCategory(final String pValue) {
381 getValues().setUncheckedValue(MoneyWiseBasicResource.CATEGORY_SUBCAT, pValue);
382 }
383
384 @Override
385 public MoneyWiseDataSet getDataSet() {
386 return (MoneyWiseDataSet) super.getDataSet();
387 }
388
389 @Override
390 public MoneyWiseCategoryBaseList<?> getList() {
391 return (MoneyWiseCategoryBaseList<?>) super.getList();
392 }
393
394 @Override
395 public MoneyWiseCategoryBase getBase() {
396 return (MoneyWiseCategoryBase) super.getBase();
397 }
398
399 @Override
400 public int compareValues(final PrometheusDataItem pThat) {
401
402 final MoneyWiseCategoryBase myThat = (MoneyWiseCategoryBase) pThat;
403 int iDiff = MetisDataDifference.compareObject(getCategoryType(), myThat.getCategoryType());
404 if (iDiff == 0) {
405 iDiff = MetisDataDifference.compareObject(getName(), myThat.getName());
406 }
407 return iDiff;
408 }
409
410 @Override
411 public void resolveDataSetLinks() throws OceanusException {
412
413 super.resolveDataSetLinks();
414
415
416 resolveDataLink(PrometheusDataResource.DATAGROUP_PARENT, getList());
417 }
418
419
420
421
422
423
424 protected abstract void resolveEditSetLinks() throws OceanusException;
425
426
427
428
429 private void resolveSubCategory() {
430
431 setValueSubCategory(null);
432
433
434 final String myName = getName();
435 if (myName != null) {
436
437 final int iIndex = myName.indexOf(STR_SEP);
438 if (iIndex != -1) {
439
440 final String mySub = myName.substring(iIndex + 1);
441 setValueSubCategory(mySub);
442 }
443 }
444 }
445
446
447
448
449
450
451
452 public void setCategoryName(final String pName) throws OceanusException {
453 setValueName(pName);
454
455
456 resolveSubCategory();
457 }
458
459
460
461
462
463
464
465
466 public void setCategoryName(final String pParentName,
467 final String pSubCatName) throws OceanusException {
468 setCategoryName(pParentName + STR_SEP + pSubCatName);
469 }
470
471
472
473
474
475
476
477 public void setSubCategoryName(final String pName) throws OceanusException {
478
479 final MoneyWiseCategoryBase myParent = getParentCategory();
480 final String myName = getName();
481 boolean updateChildren = false;
482
483
484 if (myParent != null) {
485
486 final MoneyWiseCategoryInterface myClass = myParent.getCategoryTypeClass();
487
488
489 if (myClass.isTotals()) {
490 setCategoryName(pName);
491 updateChildren = !pName.equals(myName);
492 } else {
493 setCategoryName(myParent.getName(), pName);
494 }
495
496
497 } else {
498 setCategoryName(pName);
499 if (!getCategoryTypeClass().isTotals()) {
500 updateChildren = !pName.equals(myName);
501 }
502 }
503
504
505 if (updateChildren) {
506 final MoneyWiseCategoryBaseList<?> myList = getList();
507 myList.updateChildren(myList.getBaseClass().cast(this));
508 }
509 }
510
511
512
513
514
515
516 public abstract void setCategoryType(PrometheusStaticDataItem pType);
517
518
519
520
521
522
523
524 public void setDescription(final String pDesc) throws OceanusException {
525 setValueDesc(pDesc);
526 }
527
528
529
530
531
532
533
534 public void setParentCategory(final MoneyWiseCategoryBase pParent) throws OceanusException {
535 setValueParent(pParent);
536 final String mySubName = getSubCategory();
537 if (mySubName != null) {
538 setSubCategoryName(mySubName);
539 }
540 }
541
542 @Override
543 public void touchUnderlyingItems() {
544
545 getCategoryType().touchItem(this);
546
547
548 final MoneyWiseCategoryBase myParent = getParentCategory();
549 if (myParent != null) {
550 myParent.touchItem(this);
551 }
552 }
553
554
555
556
557
558
559 public void applyBasicChanges(final MoneyWiseCategoryBase pCategory) {
560
561 if (!MetisDataDifference.isEqual(getName(), pCategory.getName())) {
562 setValueName(pCategory.getNameField());
563 }
564
565
566 if (!MetisDataDifference.isEqual(getDesc(), pCategory.getDesc())) {
567 setValueDesc(pCategory.getDescField());
568 }
569
570
571 if (!MetisDataDifference.isEqual(getParentCategory(), pCategory.getParentCategory())) {
572
573 setValueParent(pCategory.getParentCategory());
574 }
575 }
576
577 @Override
578 public void adjustMapForItem() {
579 final MoneyWiseCategoryBaseList<?> myList = getList();
580 final MoneyWiseCategoryDataMap<?> myMap = myList.getDataMap();
581 myMap.adjustForItem(myList.getBaseClass().cast(this));
582 }
583
584 @Override
585 public void touchOnUpdate() {
586
587 clearTouches(getItemType());
588
589
590 final MoneyWiseCategoryBase myParent = getParentCategory();
591 if (myParent != null) {
592 myParent.touchItem(this);
593 }
594 }
595
596
597
598
599
600
601 public abstract static class MoneyWiseCategoryBaseList<T extends MoneyWiseCategoryBase>
602 extends PrometheusEncryptedList<T> {
603
604
605
606 static {
607 MetisFieldSet.newFieldSet(MoneyWiseCategoryBaseList.class);
608 }
609
610
611
612
613
614
615
616
617 protected MoneyWiseCategoryBaseList(final MoneyWiseDataSet pData,
618 final Class<T> pClass,
619 final MoneyWiseBasicDataType pItemType) {
620 super(pClass, pData, pItemType, PrometheusListStyle.CORE);
621 }
622
623
624
625
626
627
628 protected MoneyWiseCategoryBaseList(final MoneyWiseCategoryBaseList<T> pSource) {
629 super(pSource);
630 }
631
632 @Override
633 public MoneyWiseDataSet getDataSet() {
634 return (MoneyWiseDataSet) super.getDataSet();
635 }
636
637 @Override
638 @SuppressWarnings("unchecked")
639 public MoneyWiseCategoryDataMap<T> getDataMap() {
640 return (MoneyWiseCategoryDataMap<T>) super.getDataMap();
641 }
642
643 @Override
644 @SuppressWarnings("unchecked")
645 public MoneyWiseDataValidatorParentDefaults<T> getValidator() {
646 return (MoneyWiseDataValidatorParentDefaults<T>) super.getValidator();
647 }
648
649 @Override
650 public T findItemByName(final String pName) {
651
652 final MoneyWiseCategoryDataMap<T> myMap = getDataMap();
653
654
655 if (myMap != null) {
656 return myMap.findItemByName(pName);
657 }
658
659
660 final Iterator<T> myIterator = iterator();
661 while (myIterator.hasNext()) {
662 final T myItem = myIterator.next();
663
664
665 if (!myItem.isDeleted()
666 && MetisDataDifference.isEqual(pName, myItem.getName())) {
667
668 return myItem;
669 }
670 }
671
672
673 return null;
674 }
675
676
677
678
679
680
681
682 private void updateChildren(final MoneyWiseCategoryBase pParent) throws OceanusException {
683
684 final Integer myId = pParent.getIndexedId();
685 final String myName = pParent.getName();
686
687
688 final Iterator<T> myIterator = iterator();
689 while (myIterator.hasNext()) {
690 final T myCurr = myIterator.next();
691
692
693 if (myId.equals(myCurr.getParentCategoryId())) {
694
695 myCurr.pushHistory();
696 myCurr.setParentCategory(pParent);
697 myCurr.setCategoryName(myName, myCurr.getSubCategory());
698 myCurr.checkForHistory();
699 }
700 }
701 }
702
703
704
705
706
707
708 public void resolveUpdateSetLinks() throws OceanusException {
709
710 final Iterator<T> myIterator = iterator();
711 while (myIterator.hasNext()) {
712 final T myCurr = myIterator.next();
713 myCurr.resolveEditSetLinks();
714 }
715 }
716
717 @Override
718 protected MoneyWiseCategoryDataMap<T> allocateDataMap() {
719 return new MoneyWiseCategoryDataMap<>();
720 }
721 }
722
723
724
725
726
727
728 public static class MoneyWiseCategoryDataMap<T extends MoneyWiseCategoryBase>
729 extends PrometheusDataInstanceMap<T, String> {
730 @Override
731 @SuppressWarnings("unchecked")
732 public void adjustForItem(final PrometheusDataItem pItem) {
733
734 final T myItem = (T) pItem;
735
736
737 adjustForItem((T) pItem, myItem.getName());
738 }
739
740
741
742
743
744
745
746 public T findItemByName(final String pName) {
747 return findItemByKey(pName);
748 }
749
750
751
752
753
754
755
756 public boolean validNameCount(final String pName) {
757 return validKeyCount(pName);
758 }
759
760
761
762
763
764
765
766 public boolean availableName(final String pName) {
767 return availableKey(pName);
768 }
769 }
770 }