1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.metis.field;
18
19 import io.github.tonywasher.joceanus.metis.data.MetisDataDifference;
20 import io.github.tonywasher.joceanus.metis.data.MetisDataEditState;
21 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
22 import io.github.tonywasher.joceanus.metis.data.MetisDataResource;
23 import io.github.tonywasher.joceanus.metis.data.MetisDataState;
24 import io.github.tonywasher.joceanus.metis.field.MetisFieldValidation.MetisFieldError;
25 import io.github.tonywasher.joceanus.metis.field.MetisFieldVersion.MetisFieldVersionedItemCtl;
26 import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
27
28
29
30
31 public abstract class MetisFieldVersionedItem
32 implements MetisFieldVersionedItemCtl {
33
34
35
36 private static final MetisFieldVersionedSet<MetisFieldVersionedItem> FIELD_DEFS = MetisFieldVersionedSet.newVersionedFieldSet(MetisFieldVersionedItem.class);
37
38
39
40
41 static {
42 FIELD_DEFS.declareLocalField(MetisDataResource.DATA_ID, MetisFieldVersionedItem::getIndexedId);
43 FIELD_DEFS.declareLocalField(MetisDataResource.DATA_ITEMTYPE, MetisFieldVersionedItem::getItemType);
44 FIELD_DEFS.declareLocalField(MetisDataResource.DATA_VERSION, MetisFieldVersionedItem::getVersion);
45 FIELD_DEFS.declareLocalField(MetisDataResource.DATA_DELETED, MetisFieldVersionedItem::isDeleted);
46 FIELD_DEFS.declareLocalField(MetisDataResource.DATA_STATE, MetisFieldVersionedItem::getState);
47 FIELD_DEFS.declareLocalField(MetisDataResource.DATA_EDITSTATE, MetisFieldVersionedItem::getEditState);
48 FIELD_DEFS.declareLocalField(MetisDataResource.DATA_HISTORY, MetisFieldVersionedItem::getValuesHistory);
49 FIELD_DEFS.declareLocalField(MetisDataResource.DATA_ERRORS, MetisFieldVersionedItem::getValidation);
50 }
51
52
53
54
55 private final MetisFieldVersionHistory theHistory;
56
57
58
59
60 private final MetisFieldValidation theValidation;
61
62
63
64
65 private Integer theId;
66
67
68
69
70 private MetisFieldItemType theItemType;
71
72
73
74
75 private MetisDataEditState theEditState;
76
77
78
79
80 protected MetisFieldVersionedItem() {
81
82 final MetisFieldVersionValues myValues = newVersionValues();
83 theHistory = new MetisFieldVersionHistory(myValues);
84
85
86 theValidation = new MetisFieldValidation();
87 theEditState = MetisDataEditState.CLEAN;
88 }
89
90
91
92
93
94
95 protected MetisFieldVersionedItem(final MetisFieldVersionValues pValues) {
96
97 theHistory = new MetisFieldVersionHistory(pValues);
98
99
100 theValidation = new MetisFieldValidation();
101 }
102
103
104
105
106
107
108 protected MetisFieldVersionValues newVersionValues() {
109 return new MetisFieldVersionValues(this);
110 }
111
112 @Override
113 public Integer getIndexedId() {
114 return theId;
115 }
116
117
118
119
120
121
122 public void setIndexedId(final Integer pId) {
123 theId = pId;
124 }
125
126
127
128
129
130
131 public MetisFieldItemType getItemType() {
132 return theItemType;
133 }
134
135
136
137
138
139
140 public void setItemType(final MetisFieldItemType pItemType) {
141 theItemType = pItemType;
142 }
143
144
145
146
147
148
149 public MetisDataState getState() {
150 return determineState();
151 }
152
153
154
155
156
157
158 public MetisDataEditState getEditState() {
159 return theEditState;
160 }
161
162 @Override
163 public MetisFieldVersionHistory getValuesHistory() {
164 return theHistory;
165 }
166
167
168
169
170
171
172 public MetisFieldValidation getValidation() {
173 return theValidation;
174 }
175
176 @Override
177 public MetisFieldVersionValues getValues() {
178 return theHistory.getValueSet();
179 }
180
181 @Override
182 public MetisFieldVersionValues getOriginalValues() {
183 return theHistory.getOriginalValues();
184 }
185
186
187
188
189
190
191 public Integer getVersion() {
192 return getValues().getVersion();
193 }
194
195
196
197
198
199
200 public Integer getOriginalVersion() {
201 return getOriginalValues().getVersion();
202 }
203
204 @Override
205 public boolean isDeleted() {
206 return getValues().isDeletion();
207 }
208
209 @Override
210 public void setDeleted(final boolean pFlag) {
211
212 if (pFlag != isDeleted()) {
213
214 pushHistory();
215 getValues().setDeletion(pFlag);
216 }
217 }
218
219 @Override
220 public MetisFieldSetDef getDataFieldSet() {
221 return FIELD_DEFS;
222 }
223
224 @Override
225 public String formatObject(final OceanusDataFormatter pFormatter) {
226 return FIELD_DEFS.getName();
227 }
228
229
230
231
232
233
234 protected void setEditState(final MetisDataEditState pState) {
235 theEditState = pState;
236 }
237
238
239
240
241
242
243 public boolean hasErrors() {
244 return theEditState == MetisDataEditState.ERROR;
245 }
246
247
248
249
250
251
252 public boolean hasChanges() {
253 return theEditState != MetisDataEditState.CLEAN;
254 }
255
256
257
258
259
260
261 public boolean isValid() {
262 return theEditState == MetisDataEditState.CLEAN
263 || theEditState == MetisDataEditState.VALID;
264 }
265
266 @Override
267 public boolean hasErrors(final MetisDataFieldId pFieldId) {
268 return pFieldId != null
269 && theValidation.hasErrors(pFieldId);
270 }
271
272
273
274
275
276
277
278 public void addError(final String pError,
279 final MetisDataFieldId pFieldId) {
280
281 theEditState = MetisDataEditState.ERROR;
282 theValidation.addError(pError, pFieldId);
283 }
284
285
286
287
288 public void clearErrors() {
289 theEditState = getValues().getVersion() > 0
290 ? MetisDataEditState.DIRTY
291 : MetisDataEditState.CLEAN;
292 theValidation.clearErrors();
293 }
294
295
296
297
298
299
300 public MetisFieldError getFirstError() {
301 return theValidation.getFirst();
302 }
303
304 @Override
305 public String getFieldErrors(final MetisDataFieldId pField) {
306 return pField != null
307 ? theValidation.getFieldErrors(pField)
308 : null;
309 }
310
311 @Override
312 public String getFieldErrors(final MetisDataFieldId[] pFields) {
313 final MetisFieldSetDef myFieldSet = getDataFieldSet();
314 final MetisFieldDef[] myFields = new MetisFieldDef[pFields.length];
315 for (int i = 0; i < pFields.length; i++) {
316 myFields[i] = myFieldSet.getField(pFields[i]);
317 }
318 return theValidation.getFieldErrors(myFields);
319 }
320
321
322
323
324
325
326 public void setValues(final MetisFieldVersionValues pValues) {
327 theHistory.setValues(pValues);
328 adjustState();
329 }
330
331 @Override
332 public void pushHistory() {
333 final int myVersion = getNextVersion();
334 theHistory.pushHistory(myVersion);
335 }
336
337
338
339
340
341
342 public void pushHistory(final int pVersion) {
343 theHistory.pushHistory(pVersion);
344 }
345
346 @Override
347 public void popHistory() {
348 theHistory.popTheHistory();
349 }
350
351
352
353
354
355
356 public boolean maybePopHistory() {
357 return theHistory.maybePopHistory();
358 }
359
360
361
362
363
364
365 public boolean hasHistory() {
366 return theHistory.hasHistory();
367 }
368
369
370
371
372 public void clearHistory() {
373 theHistory.clearHistory();
374 adjustState();
375 }
376
377
378
379
380 public void resetHistory() {
381 theHistory.resetHistory();
382 adjustState();
383 }
384
385
386
387
388
389
390 public void setHistory(final MetisFieldVersionValues pBase) {
391 theHistory.setHistory(pBase);
392 adjustState();
393 }
394
395 @Override
396 public boolean checkForHistory() {
397 return theHistory.maybePopHistory();
398 }
399
400
401
402
403
404
405 public void condenseHistory(final int pNewVersion) {
406 theHistory.condenseHistory(pNewVersion);
407 }
408
409
410
411
412
413
414 public void rewindToVersion(final int pVersion) {
415
416 while (getValues().getVersion() > pVersion) {
417
418 getValuesHistory().popTheHistory();
419 }
420 }
421
422
423
424
425
426
427
428 public MetisDataDifference fieldChanged(final MetisDataFieldId pField) {
429 final MetisFieldDef myField = getDataFieldSet().getField(pField);
430 return theHistory.fieldChanged(myField);
431 }
432
433
434
435
436
437
438
439 public MetisDataDifference fieldChanged(final MetisFieldDef pField) {
440 return theHistory.fieldChanged(pField);
441 }
442
443
444
445
446 public void adjustState() {
447 theEditState = determineEditState();
448 }
449
450
451
452
453
454
455 private MetisDataState determineState() {
456 final MetisFieldVersionValues myCurr = getValues();
457 final MetisFieldVersionValues myOriginal = getOriginalValues();
458
459
460 if (myOriginal.getVersion() > 0) {
461
462 return myCurr.isDeletion()
463 ? MetisDataState.DELNEW
464 : MetisDataState.NEW;
465 }
466
467
468 if (myCurr.getVersion() == 0) {
469 return MetisDataState.CLEAN;
470 }
471
472
473 if (myCurr.isDeletion()) {
474 return MetisDataState.DELETED;
475 }
476
477
478 return MetisDataState.CHANGED;
479 }
480
481
482
483
484
485
486 private MetisDataEditState determineEditState() {
487
488 if (theValidation.hasErrors()) {
489
490 return MetisDataEditState.ERROR;
491 }
492
493
494 return getVersion() == 0
495 ? MetisDataEditState.CLEAN
496 : MetisDataEditState.DIRTY;
497 }
498
499
500
501
502
503
504
505 public MetisFieldVersionedDef getVersionedField(final MetisDataFieldId pId) {
506 final MetisFieldDef myField = getDataFieldSet().getField(pId);
507 return myField instanceof MetisFieldVersionedDef myVersioned
508 ? myVersioned
509 : null;
510 }
511 }