Skip to content

refactor: extract fixedformat4j-core — shared formatter layer prerequisite for multi-format support #121

Description

@jeyben

Summary

FixedFormatter<T>, FormatInstructions, FormatContext, and all typed formatters (DateFormatter, BigDecimalFormatter, StringFormatter, etc.) currently live inside the fixedformat4j Maven artifact. This couples them to the fixed-width format. Extending the library to support additional formats (delimited, COBOL/EBCDIC, SWIFT MT) requires these shared building blocks to live in a format-neutral fixedformat4j-core artifact that each format module can depend on independently.

This issue is a prerequisite for #122 (delimited file support) and any subsequent format modules.

Motivation

Without extraction, a fixedformat4j-delimited module would have to duplicate DateFormatter, BigDecimalFormatter, BooleanFormatter, and every other typed formatter — or take a hard dependency on the fixed-width artifact, which makes no semantic sense. The extraction decouples the type formatting layer from the fixed-width framing concern.

Proposed module structure

fixedformat4j-root
├── fixedformat4j-core       ← NEW: shared formatter layer
├── fixedformat4j            ← fixed-width (depends on fixedformat4j-core)
├── fixedformat4j-delimited  ← CSV/pipe (depends on fixedformat4j-core)
├── fixedformat4j-processor  ← annotation processor (future)
└── fixedformat4j-micrometer ← instrumentation (future)

What moves to fixedformat4j-core

Class / interface Current location Reason to move
FixedFormatter<T> format/ The formatter contract — format-neutral
FormatInstructions format/ Carries field-level config into formatters
FormatContext<T> format/ Carries type and formatter class — format-neutral
FixedFormatException exception/ Root exception — shared across formats
ParseException format/ Shared parse failure type
All typed formatters format/impl/ StringFormatter, IntegerFormatter, LongFormatter, ShortFormatter, DoubleFormatter, FloatFormatter, BigDecimalFormatter, BooleanFormatter, CharacterFormatter, DateFormatter, LocalDateFormatter, LocalDateTimeFormatter, EnumFormatter
AbstractFixedFormatter format/impl/ Base class for typed formatters — only the padding/alignment logic is fixed-width-specific and should be separated out
Supplementary annotation data objects format/data/ FixedFormatBooleanData, FixedFormatDecimalData, FixedFormatNumberData, FixedFormatPatternData, FixedFormatEnumData

What stays in fixedformat4j (fixed-width only)

  • @Record, @Field, @Fields and all supplementary field annotations
  • FixedFormatManager and FixedFormatManagerImpl
  • ClassMetadataCache, AnnotationScanner, FieldDescriptor, FormatInstructionsBuilder
  • NullCharSupport, RepeatingFieldSupport, RecordInstantiator, PatternValidator
  • FixedFormatUtil (fixed-width slicing logic)
  • io/read/FixedFormatReader and all IO types
  • FixedFormatIOException

Breaking change analysis

Moving classes to a new artifact changes their Maven coordinates, not their package names. If packages are preserved (com.ancientprogramming.fixedformat4j.format, com.ancientprogramming.fixedformat4j.exception), source compatibility is retained — existing code that imports FixedFormatter<T> continues to compile without changes.

The runtime classpath changes: consumers who currently declare only fixedformat4j will need fixedformat4j-core on their classpath. This is handled transparently by Maven transitive dependencies — fixedformat4j depends on fixedformat4j-core, so existing consumers gain it automatically without changing their pom.xml.

The only consumers who need an explicit change are those who directly declare a dependency on fixedformat4j-core classes while only listing fixedformat4j in their POM — which works via transitive resolution, requiring no action.

SOLID check

  • SRP: fixedformat4j-core has one responsibility — the type formatting contract and implementations. Fixed-width framing stays in fixedformat4j.
  • OCP: existing formatter implementations are unchanged; the extraction is purely structural.
  • DIP: format modules depend on the FixedFormatter<T> abstraction in core, not on each other.

Version classification

Major (2.0.0) — while source compatibility is preserved, the Maven artifact restructuring is a deployment-visible change. Consumers who pin to fixedformat4j and introspect the classpath (e.g. via OSGi, shading, or fat-jar assembly) may need to account for the new artifact. A major version signals this structural shift clearly and sets the foundation for the multi-format roadmap.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Module-CoreTouches the main fixedformat4j artifact (annotation, format, format/impl layers)Module-DelimitedTouches the fixedformat4j-delimited artifact (CSV/TSV/pipe-delimited support)Type-Enhancementenhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions