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