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.MetisDataResource;
22
23 import java.util.ArrayDeque;
24 import java.util.Deque;
25 import java.util.Iterator;
26
27
28
29
30 public class MetisFieldVersionHistory
31 implements MetisFieldItem {
32
33
34
35 static {
36 MetisFieldSet.newFieldSet(MetisFieldVersionHistory.class);
37 }
38
39
40
41
42 private final Deque<MetisFieldVersionValues> theStack;
43
44
45
46
47 private final Deque<MetisFieldVersionDelta> theDeltas;
48
49
50
51
52 private MetisFieldVersionValues theCurr;
53
54
55
56
57 private MetisFieldVersionValues theOriginal;
58
59
60
61
62
63
64 protected MetisFieldVersionHistory(final MetisFieldVersionValues pCurr) {
65
66 theCurr = pCurr;
67 theOriginal = theCurr;
68
69
70 theStack = new ArrayDeque<>();
71 theDeltas = new ArrayDeque<>();
72 }
73
74 @Override
75 public MetisFieldSetDef getDataFieldSet() {
76
77 final MetisFieldSet<MetisFieldVersionHistory> myLocal = MetisFieldSet.newFieldSet(this);
78 final String myVersion = MetisDataResource.DATA_VERSION.getValue();
79
80
81 final Iterator<MetisFieldVersionDelta> myIterator = theDeltas.descendingIterator();
82 while (myIterator.hasNext()) {
83
84 final MetisFieldVersionDelta myDelta = myIterator.next();
85
86
87 myLocal.declareLocalField(myVersion + "(" + myDelta.getVersion() + ")", f -> myDelta);
88 }
89
90
91 return myLocal;
92 }
93
94 @Override
95 public String formatObject(final OceanusDataFormatter pFormatter) {
96 return MetisFieldVersionHistory.class.getSimpleName() + "(" + theStack.size() + ")";
97 }
98
99
100
101
102
103
104 protected void setValues(final MetisFieldVersionValues pValues) {
105
106 theCurr = pValues;
107 theOriginal = theCurr;
108 theStack.clear();
109 theDeltas.clear();
110 }
111
112
113
114
115
116
117 protected MetisFieldVersionValues getValueSet() {
118 return theCurr;
119 }
120
121
122
123
124
125
126 protected MetisFieldVersionValues getOriginalValues() {
127 return theOriginal;
128 }
129
130
131
132
133
134
135 public void pushHistory(final int pVersion) {
136
137 final MetisFieldVersionValues mySet = theCurr.cloneIt();
138 mySet.setVersion(pVersion);
139
140
141 theDeltas.push(new MetisFieldVersionDelta(mySet, theCurr));
142
143
144 theStack.push(theCurr);
145 theCurr = mySet;
146 }
147
148
149
150
151 public void popTheHistory() {
152
153 if (hasHistory()) {
154
155 theCurr = theStack.pop();
156 theDeltas.pop();
157 }
158 }
159
160
161
162
163
164
165 public boolean maybePopHistory() {
166
167 if (!theStack.isEmpty()
168 && theCurr.differs(theStack.peek()).isIdentical()) {
169
170 popTheHistory();
171 return false;
172 }
173
174
175 return true;
176 }
177
178
179
180
181
182
183 public boolean hasHistory() {
184 return !theStack.isEmpty();
185 }
186
187
188
189
190
191
192 public MetisFieldVersionValues getLastValues() {
193 return theStack.peek();
194 }
195
196
197
198
199 protected void clearHistory() {
200
201 theStack.clear();
202 theDeltas.clear();
203 theOriginal = theCurr;
204 theOriginal.setVersion(0);
205 }
206
207
208
209
210 protected void resetHistory() {
211
212 theStack.clear();
213 theDeltas.clear();
214 theCurr = theOriginal;
215 }
216
217
218
219
220
221
222 public void setHistory(final MetisFieldVersionValues pBase) {
223 theStack.clear();
224 theDeltas.clear();
225 theOriginal = theCurr.cloneIt();
226 theOriginal.copyFrom(pBase);
227 theStack.push(theOriginal);
228 theCurr.setVersion(1);
229
230
231 theDeltas.push(new MetisFieldVersionDelta(theCurr, theOriginal));
232 }
233
234
235
236
237
238
239 protected void condenseHistory(final int pNewVersion) {
240
241 if (theCurr.getVersion() > pNewVersion) {
242
243 boolean bNewDelta = false;
244 while (!theStack.isEmpty()
245 && theStack.peek().getVersion() >= pNewVersion) {
246
247 theStack.pop();
248 theDeltas.pop();
249 bNewDelta = true;
250 }
251
252
253 theCurr.setVersion(pNewVersion);
254
255
256 if (bNewDelta && !theStack.isEmpty()) {
257
258 theDeltas.pop();
259
260
261 theDeltas.push(new MetisFieldVersionDelta(theCurr, theStack.peek()));
262 }
263 }
264 }
265
266
267
268
269
270
271
272 public MetisDataDifference fieldChanged(final MetisFieldDef pField) {
273
274 if (!(pField instanceof MetisFieldVersionedDef)) {
275 return MetisDataDifference.IDENTICAL;
276 }
277 if (!((MetisFieldVersionedDef) pField).isEquality()) {
278 return MetisDataDifference.IDENTICAL;
279 }
280
281
282 return theCurr.fieldChanged(pField, theOriginal);
283 }
284 }