Package de.bsommerfeld.jshepherd.core
Class AbstractPersistenceDelegate<T>
java.lang.Object
de.bsommerfeld.jshepherd.core.AbstractPersistenceDelegate<T>
- All Implemented Interfaces:
PersistenceDelegate<T>
public abstract class AbstractPersistenceDelegate<T>
extends Object
implements PersistenceDelegate<T>
Abstract base class for all persistence delegates.
Provides common functionality for file operations, type conversion,
comment writing, and reflection-based data mapping.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected static interfaceAbstraction for extracting values from different data formats. -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected final Pathprotected static final intSafety cap for recursive@Sectionnesting, protecting against accidental cycles in section POJO graphs.protected final boolean -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedAbstractPersistenceDelegate(Path filePath, boolean useComplexSaveWithComments) -
Method Summary
Modifier and TypeMethodDescriptionprotected final voidapplyDataToInstance(T target, AbstractPersistenceDelegate.DataExtractor extractor) Applies data from parsed format to POJO instance using reflection.protected final ObjectconvertNumericIfNeeded(Object value, Class<?> targetType) Converts values to match the target type.protected final ObjectconvertValueForField(Object value, Field field) Converts a raw parsed value to the field's type, including element-wise conversion for typed lists and maps (e.g.Returns the per-key issues recorded during the last load or reload.getNonSectionFields(Class<?> clazz, Class<?> stopClass) Gets all non-section fields (regular @Key fields) from a class.getSectionFields(Class<?> clazz, Class<?> stopClass) Gets all section fields from a class.getSectionPojoFields(Object sectionPojo) Gets all fields from a nested section POJO that have @Key annotation.getSectionPojoSubsectionFields(Object sectionPojo) Gets all nested@Sectionfields of a section POJO, enabling recursive section nesting.protected final booleanisEnumType(Class<?> type) Checks if the given type is an enum type.protected final booleanChecks if a field is annotated with @Section.final TloadInitial(Supplier<T> defaultPojoSupplier) Loads the initial POJO instance from the persistent store, or creates and saves a default if the store is new or empty.protected final voidrecordLoadIssue(String key, Object rawValue, Class<?> targetType, Exception cause) Records a value that could not be applied to its field.final voidReloads data from the persistent store into the provided POJO instance, updating its fields.protected final Class<?> resolveGenericClass(Field field, int index) Resolves the class of a field's generic type argument (e.g. the element type of aList<Integer>), or null if not determinable.protected final StringresolveKey(Field field) Resolves the configuration key for a field, using @Key annotation value or field name.protected final StringresolveSectionName(Field field) Resolves the section name from @Section annotation, falling back to @Key or field name.final voidSaves the provided POJO instance to the persistent store.protected abstract voidsaveSimple(T pojoInstance, Path targetPath) Format-specific simple save implementation.protected abstract voidsaveWithComments(T pojoInstance, Path targetPath) Format-specific save with comments implementation.protected final StringserializeEnumValue(Object enumValue) Returns the constant name of an enum value for format-agnostic serialization.protected final booleanshouldSkipField(Field field) Checks if a field should be skipped during persistence operations.protected abstract booleantryLoadFromFile(T instance) Format-specific loading implementation.protected final voidwriteClassComments(PrintWriter writer, T pojoInstance) Writes class-level comments (file header) from @Comment annotation on the POJO class.protected final voidwriteFieldComments(PrintWriter writer, Field field) Writes field-level comments from @Comment annotation.
-
Field Details
-
MAX_SECTION_DEPTH
protected static final int MAX_SECTION_DEPTHSafety cap for recursive@Sectionnesting, protecting against accidental cycles in section POJO graphs.- See Also:
-
filePath
-
useComplexSaveWithComments
protected final boolean useComplexSaveWithComments
-
-
Constructor Details
-
AbstractPersistenceDelegate
-
-
Method Details
-
loadInitial
Description copied from interface:PersistenceDelegateLoads the initial POJO instance from the persistent store, or creates and saves a default if the store is new or empty.- Specified by:
loadInitialin interfacePersistenceDelegate<T>- Parameters:
defaultPojoSupplier- Supplier for creating a default POJO instance.- Returns:
- The loaded or newly created default POJO instance.
-
save
Description copied from interface:PersistenceDelegateSaves the provided POJO instance to the persistent store.- Specified by:
savein interfacePersistenceDelegate<T>- Parameters:
pojoInstance- The POJO instance to save.
-
reload
Description copied from interface:PersistenceDelegateReloads data from the persistent store into the provided POJO instance, updating its fields.- Specified by:
reloadin interfacePersistenceDelegate<T>- Parameters:
pojoInstanceToUpdate- The POJO instance whose fields should be updated.
-
getLastLoadIssues
Description copied from interface:PersistenceDelegateReturns the per-key issues recorded during the last load or reload.- Specified by:
getLastLoadIssuesin interfacePersistenceDelegate<T>- Returns:
- an immutable list; empty if the last load was clean
-
convertNumericIfNeeded
Converts values to match the target type. Handles numeric widening/narrowing and String-to-Enum conversion. -
isEnumType
Checks if the given type is an enum type. -
serializeEnumValue
Returns the constant name of an enum value for format-agnostic serialization. -
applyDataToInstance
protected final void applyDataToInstance(T target, AbstractPersistenceDelegate.DataExtractor extractor) Applies data from parsed format to POJO instance using reflection. -
convertValueForField
Converts a raw parsed value to the field's type, including element-wise conversion for typed lists and maps (e.g. TOML integers arrive as Long and must be narrowed for aList<Integer>field). -
resolveGenericClass
Resolves the class of a field's generic type argument (e.g. the element type of aList<Integer>), or null if not determinable. -
recordLoadIssue
protected final void recordLoadIssue(String key, Object rawValue, Class<?> targetType, Exception cause) Records a value that could not be applied to its field. The issue is logged and made available to the user viaConfigurablePojo.getLastLoadIssues()after the load completes, so it can be validated in@PostInjectmethods. -
shouldSkipField
Checks if a field should be skipped during persistence operations. Skips static and transient fields. -
writeClassComments
Writes class-level comments (file header) from @Comment annotation on the POJO class. -
writeFieldComments
Writes field-level comments from @Comment annotation. -
resolveKey
Resolves the configuration key for a field, using @Key annotation value or field name. -
isSection
Checks if a field is annotated with @Section. -
resolveSectionName
Resolves the section name from @Section annotation, falling back to @Key or field name. -
getNonSectionFields
Gets all non-section fields (regular @Key fields) from a class. These should be written first, before any sections. -
getSectionFields
Gets all section fields from a class. These should be written after regular fields. -
getSectionPojoFields
Gets all fields from a nested section POJO that have @Key annotation. Section POJOs don't extend ConfigurablePojo, so we use Object as stop class. -
getSectionPojoSubsectionFields
Gets all nested@Sectionfields of a section POJO, enabling recursive section nesting. Guard recursion withMAX_SECTION_DEPTH. -
tryLoadFromFile
Format-specific loading implementation.- Returns:
- true if data was loaded successfully, false if file was empty
- Throws:
Exception
-
saveSimple
Format-specific simple save implementation.- Throws:
IOException
-
saveWithComments
Format-specific save with comments implementation.- Throws:
IOException
-