Skip to content

Commit 5876882

Browse files
committed
Add applyData and applyAppearance
1 parent 2b994bc commit 5876882

1 file changed

Lines changed: 115 additions & 51 deletions

File tree

patternfx-mvp/src/main/java/com/techsenger/patternfx/mvp/AbstractComponentPresenter.java

Lines changed: 115 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,7 @@ public final void initialize() {
6262
if (getView() instanceof AbstractView<?>) {
6363
((AbstractComponentView<?>) getView()).initialize();
6464
}
65-
if (this.history != null) {
66-
restoreHistory();
67-
}
65+
applyOrRestoreHistory();
6866
descriptor.setState(ComponentState.INITIALIZED);
6967
logger.debug("{} Initialized the component", getDescriptor().getLogPrefix());
7068
// post-initialization
@@ -85,9 +83,7 @@ public final void deinitialize() {
8583
preDeinitialize();
8684
// deinitialization
8785
descriptor.setState(ComponentState.DEINITIALIZING);
88-
if (this.history != null) {
89-
saveHistory();
90-
}
86+
saveHistory();
9187
if (getView() instanceof AbstractView<?>) {
9288
((AbstractComponentView<?>) getView()).deinitialize();
9389
}
@@ -148,25 +144,23 @@ protected void setHistoryProvider(@Nullable HistoryProvider<? extends AbstractCo
148144
return history;
149145
}
150146

151-
protected final void restoreHistory() {
152-
var policy = getHistoryPolicy();
153-
logger.debug("{} History policy during restore: {}", getDescriptor().getLogPrefix(), policy);
154-
if (policy != NONE && history != null) {
155-
if (history.isNew()) {
156-
logger.debug("{} History is new. Skipping restoration", getDescriptor().getLogPrefix());
157-
} else {
158-
switch (policy) {
159-
case DATA -> restoreData();
160-
case APPEARANCE -> restoreAppearance();
161-
case ALL -> {
162-
restoreData();
163-
restoreAppearance();
164-
}
165-
default -> throw new AssertionError();
166-
}
167-
}
168-
}
169-
}
147+
/**
148+
* Applies default values for the component's persistent data.
149+
* <p>
150+
* This method is invoked when no previously persisted data is available or when the current {@link HistoryPolicy}
151+
* does not include {@code DATA}. Implementations should assign meaningful default values to all data that
152+
* participates in the history mechanism.
153+
*/
154+
protected void applyData() { }
155+
156+
/**
157+
* Applies default values for the component's persistent appearance state.
158+
* <p>
159+
* This method is invoked when no previously persisted appearance state is available or when the current
160+
* {@link HistoryPolicy} does not include {@code APPEARANCE}. Implementations should initialize all
161+
* appearance-related state that is managed through the history mechanism.
162+
*/
163+
protected void applyAppearance() { }
170164

171165
/**
172166
* Method copies all data from history to view. This method is called at the beginning of initialization
@@ -182,49 +176,119 @@ protected void restoreData() { }
182176
*/
183177
protected void restoreAppearance() { }
184178

185-
protected final void saveHistory() {
186-
var policy = getHistoryPolicy();
187-
logger.debug("{} History policy during save: {}", getDescriptor().getLogPrefix(), policy);
188-
switch (policy) {
189-
case DATA -> saveData();
190-
case APPEARANCE -> saveAppearance();
191-
case ALL -> {
192-
saveData();
193-
saveAppearance();
194-
}
195-
case NONE -> { }
196-
default -> throw new AssertionError();
197-
}
198-
}
199-
200179
/**
201180
* Method copies all data from view to history. This method is called at the beginning of deinitialization
202181
* when the policy is {@link HistoryPolicy#ALL} or {@link HistoryPolicy#DATA}.
203182
*
204183
*/
205-
protected void saveData() {
206-
if (this.history != null) {
207-
this.history.setNew(false);
208-
}
209-
}
184+
protected void saveData() { }
210185

211186
/**
212187
* Method copies all data from view to history. This method is called at the beginning of deinitialization
213188
* when the policy is {@link HistoryPolicy#ALL} or {@link HistoryPolicy#APPEARANCE}.
214189
*
215190
*/
216-
protected void saveAppearance() {
217-
if (this.history != null) {
218-
this.history.setNew(false);
219-
}
220-
}
191+
protected void saveAppearance() { }
221192

222193
protected abstract Descriptor createDescriptor();
223194

224-
void prepareHistory() {
195+
private void prepareHistory() {
225196
if (this.historyProvider != null) {
226197
this.history = this.historyProvider.provide();
227198
this.historyProvider = null;
228199
}
229200
}
201+
202+
/**
203+
* Resolves the component's persistent state by either restoring it from history or applying default values when
204+
* necessary.
205+
* <p>
206+
* The component state is divided into two categories:
207+
* <ul>
208+
* <li><b>Persistent state</b> — participates in the history mechanism and can be restored or saved across
209+
* component lifecycles.</li>
210+
* <li><b>Transient state</b> — does not participate in the history mechanism and exists only at runtime.</li>
211+
* </ul>
212+
* <p>
213+
* This method operates exclusively on the <b>persistent state</b>. It does not initialize or modify transient data.
214+
* <p>
215+
* Behavior depends on the {@link HistoryPolicy} and the state of the history:
216+
* <ul>
217+
* <li>If history is new or unavailable, default values are applied via {@link #applyData()} and
218+
* {@link #applyAppearance()}.</li>
219+
* <li>If history exists, the state is selectively restored via {@link #restoreData()} and/or
220+
* {@link #restoreAppearance()}, while missing parts are filled with defaults.</li>
221+
* </ul>
222+
*/
223+
private void applyOrRestoreHistory() {
224+
logger.debug("{} History policy during initialization: {}", getDescriptor().getLogPrefix(), historyPolicy);
225+
if (historyPolicy == NONE || history == null || history.isNew()) {
226+
applyData();
227+
applyAppearance();
228+
logger.debug("{} Data and appearance set to defaults. Reason: {}", getDescriptor().getLogPrefix(),
229+
historyPolicy == NONE ? "policy is NONE" : history == null ? "history is null" : "history is new");
230+
} else {
231+
switch (historyPolicy) {
232+
case DATA -> {
233+
restoreData();
234+
applyAppearance();
235+
logger.debug("{} Data restored from history, appearance set to defaults",
236+
getDescriptor().getLogPrefix());
237+
}
238+
case APPEARANCE -> {
239+
applyData();
240+
restoreAppearance();
241+
logger.debug("{} Data set to defaults, appearance restored from history",
242+
getDescriptor().getLogPrefix());
243+
}
244+
case ALL -> {
245+
restoreData();
246+
restoreAppearance();
247+
logger.debug("{} Data and appearance restored from history", getDescriptor().getLogPrefix());
248+
}
249+
default -> throw new AssertionError();
250+
}
251+
}
252+
}
253+
254+
/**
255+
* Saves the current persistent state of the component into its history.
256+
* <p>
257+
* The component state is conceptually divided into two categories:
258+
* <ul>
259+
* <li><b>Persistent state</b> — data that is stored in and restored from history
260+
* (e.g., user input, UI state, configuration).</li>
261+
* <li><b>Transient state</b> — runtime-only data that is not persisted and
262+
* exists only for the duration of the component's lifecycle.</li>
263+
* </ul>
264+
* <p>
265+
* This method operates exclusively on the <b>persistent state</b>. Transient state is not affected and must be
266+
* managed independently.
267+
* <p>
268+
* Depending on the {@link HistoryPolicy}, this method delegates to {@link #saveData()} and/or
269+
* {@link #saveAppearance()}.
270+
*/
271+
private void saveHistory() {
272+
if (this.history == null) {
273+
return;
274+
}
275+
logger.debug("{} History policy during deinitialization: {}", getDescriptor().getLogPrefix(), historyPolicy);
276+
switch (historyPolicy) {
277+
case DATA -> {
278+
saveData();
279+
this.history.setNew(false);
280+
}
281+
case APPEARANCE -> {
282+
saveAppearance();
283+
this.history.setNew(false);
284+
}
285+
case ALL -> {
286+
saveData();
287+
saveAppearance();
288+
this.history.setNew(false);
289+
}
290+
case NONE -> { }
291+
default -> throw new AssertionError();
292+
}
293+
}
230294
}

0 commit comments

Comments
 (0)