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