Releases: jeyben/fixedformat4j
1.7.2
1.7.1
New features
-
nullCharon@Field— opt-in sentinel to distinguish a genuinely-absent field from zero/empty. Null-aware handling is active only whennullChardiffers frompaddingChar. On load, an all-nullCharslice yieldsnull; on export, anullvalue is emitted aslength × nullChar. Works per-element for repeating fields (count > 1). (#29) -
Record-level default alignment via
@Record(align = …)— sets a default alignment for all fields in the record; individual fields may still override with an explicit@Field(align = …). (#30)
Validation improvements
Align.INHERITis now rejected on@Record(align)with a clearFixedFormatException(it is a field-only sentinel).nullCharis now rejected on@Fieldwith a primitive return type (int,long, etc.) — primitives can never benull.
1.7.0
Breaking changes
-
AbstractFixedFormatter.getRemovePaddingremoved — deprecated in 1.6.1 and now deleted.
Rename any override tostripPadding; the signature is identical. The call chain is now
parse()→stripPadding()directly.// Before (1.6.x) @Override protected String getRemovePadding(String value, FormatInstructions instructions) { … } // After (1.7.0+) @Override protected String stripPadding(String value, FormatInstructions instructions) { … }
New features
-
Enum support via
@FixedFormatEnum(#67) —
Annotate any getter that returns anenumtype with@FixedFormatEnumto control how the value
is serialised in the fixed-width record. Two modes are available through theEnumFormatenum:LITERAL(default) — stores and reads the enum constant name (Enum.name()/valueOf()).NUMERIC— stores and reads the ordinal as a zero-padded integer (Enum.ordinal()/ index lookup).
public enum Status { ACTIVE, INACTIVE } // LITERAL (default): stores "ACTIVE" / "INACTIVE" @Field(offset = 1, length = 8) @FixedFormatEnum public Status getStatus() { … } // NUMERIC: stores "0" / "1" @Field(offset = 1, length = 1) @FixedFormatEnum(EnumFormat.NUMERIC) public Status getStatus() { … }
Performance improvements
-
Field metadata caching (#77) —
ClassMetadataCacheprecomputes and caches all field descriptors per annotated class on first
use, eliminating repeated annotation scanning on everyload()/export()call. The cache is
process-wide and thread-safe. -
MethodHandle dispatch (#75) —
Getter and setter invocation now usesMethodHandleinstead ofMethod.invoke(), reducing
per-call overhead after JIT warmup. -
Reduced string allocations (#76) —
Padding and sign handling rewritten to minimise intermediateStringobject creation per field.
1.6.1
Bug fixes
DateFormatter(andLocalDateFormatter/LocalDateTimeFormatter) no longer over-strips padding characters (#33) — When the configuredpaddingCharhappened to be a character that also appears in the formatted date string (e.g.paddingChar = '0'with a time value whose seconds component is00), the previousstripPaddingimplementation removed those characters from the parsed string, leaving it too short and causing aParseException. The fix introducesAbstractPatternFormatter, which overridesstripPaddingto remove only leading/trailing padding characters rather than all occurrences of the character.
Deprecations
-
AbstractFixedFormatter.getRemovePaddingdeprecated — The method has been renamed tostripPadding, which better reflects its behaviour. The old name carried a misleadinggetprefix that implied a zero-argument accessor.getRemovePaddingremains callable and fully functional in 1.6.1; it now delegates tostripPadding. It will be removed in 1.7.0.Migration: rename any override of
getRemovePaddingtostripPadding— the signature is identical:// Before (1.6.0 and earlier) @Override protected String getRemovePadding(String value, FormatInstructions instructions) { … } // After (1.6.1+) @Override protected String stripPadding(String value, FormatInstructions instructions) { … }
1.6.0
What's New
Repeating Fields
- Added
countandstrictCountattributes to@Fieldfor repeating field support — a single annotated getter can now map to multiple consecutive fixed-width slots - Clarified
@Fieldsdocumentation: prefer@Field(count=…)for repeating fields
LocalDateTime Support
- Added built-in formatter for
java.time.LocalDateTimewith type-specific default patterns - Eager pattern validation catches misconfigured
@FixedFormatPatternat load time rather than at parse time
Mutation Testing (CI/CD)
- Added PIT mutation testing with automated GitHub Pages report publishing
- Nightly PIT report published to GitHub Pages with links from README and docs navigation
Documentation & Internals
- Added fixed left-sidebar navigation to docs
- Refactored
FixedFormatManagerImplinto focused collaborators for improved maintainability - Added public method Javadoc across all production classes
- Switched to SLF4J parameterized logging and
String.formatthroughout
Maintenance
- Issue tracker updated from Google Code to GitHub Issues
- Removed
maven-changes-plugin(changelog now maintained inCHANGELOG.md)
1.5.0
1.5.0
New features
-
Field-level
@Fieldand@Fieldsannotations —@Fieldand@Fieldscan now be placed directly on Java fields in addition to getter methods. The manager discovers them at runtime and derives the getter/setter by theget/isnaming convention. This enables clean usage with Lombok (@Getter/@Setter) and reduces boilerplate in plain POJOs.If both the field and its getter carry
@Field, an error is logged (configuration mismatch) and the field annotation is used.
1.4.0
1.4.0 (2026-04-05)
New features
-
LocalDatesupport —java.time.LocalDateis now a first-class field type handled automatically byByTypeFormatter. No custom formatter needed. Configure the date pattern with@FixedFormatPattern(default:yyyyMMdd).@Field(offset = 1, length = 8) @FixedFormatPattern("yyyyMMdd") public LocalDate getEventDate() { return eventDate; }
String
"20260405"parses toLocalDate.of(2026, 4, 5); exporting writes"20260405"back.
Breaking changes
- Java 11 minimum — Java 8 is no longer supported. The minimum required runtime is Java 11.
- Logging: SLF4J replaces Commons Logging — The library no longer depends on Apache Commons Logging. Logging is now done via SLF4J. If your project relied on the transitive
commons-loggingdependency, you will need to add an SLF4J binding instead (e.g.logback-classicorslf4j-simple). See Get It for details.
Documentation
- Added Quick Start guide, Examples page, and an enriched Annotations reference.
Fixedformat4j v1.3.7
Fixed bug in how negative decimal numbers between 0 and -1 is parsed big the decimal parser
Fixedformat4j v1.3.5
- Contains a bugfix where very small decimals would not be parsed correct
- Had to depend on java 8 as java 5 i long gone (which normally is not a bugfix thing to do)