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