Class AbstractReadHandler<T>

java.lang.Object
io.github.dornol.excelkit.core.TempResourceContainer
io.github.dornol.excelkit.core.AbstractReadHandler<T>
Type Parameters:
T - The target row data type to map each row into
All Implemented Interfaces:
AutoCloseable
Direct Known Subclasses:
CsvReadHandler, ExcelReadHandler

public abstract class AbstractReadHandler<T> extends TempResourceContainer
Abstract base class for file read handlers (Excel, CSV).

Provides common functionality including:

  • Constructor parameter validation
  • Temporary file initialization from an InputStream
  • Optional Bean Validation support
Since:
2025-07-19
  • Field Details

    • instanceSupplier

      protected final @Nullable Supplier<T> instanceSupplier
      Supplier for creating new row instances (setter mode).
    • rowMapper

      protected final @Nullable Function<RowData,T> rowMapper
      Function for mapping row data to instances (mapping mode).
    • validator

      protected final @Nullable jakarta.validation.Validator validator
      Optional bean validator for row validation.
  • Constructor Details

    • AbstractReadHandler

      protected AbstractReadHandler(InputStream inputStream, Supplier<T> instanceSupplier, @Nullable jakarta.validation.Validator validator, String extension)
      Constructs a read handler in setter mode by validating inputs and initializing a temporary file.
      Parameters:
      inputStream - The input stream of the uploaded file
      instanceSupplier - A supplier to instantiate new row objects
      validator - Optional bean validator for validating mapped instances
      extension - File extension for the temporary file (e.g., ".xlsx", ".csv")
    • AbstractReadHandler

      protected AbstractReadHandler(InputStream inputStream, Function<RowData,T> rowMapper, @Nullable jakarta.validation.Validator validator, String extension)
      Constructs a read handler in mapping mode for immutable object construction.
      Parameters:
      inputStream - The input stream of the uploaded file
      rowMapper - A function that creates an instance from a RowData
      validator - Optional bean validator for validating mapped instances
      extension - File extension for the temporary file (e.g., ".xlsx", ".csv")
  • Method Details

    • validateHeaderRowIndex

      protected static void validateHeaderRowIndex(int headerRowIndex)
      Validates that headerRowIndex is non-negative.
      Parameters:
      headerRowIndex - the header row index to validate
    • validateColumns

      protected static void validateColumns(List<?> columns)
      Validates that the columns list is non-null and non-empty.
      Parameters:
      columns - the column list to validate
    • read

      public abstract void read(Consumer<ReadResult<T>> consumer)
      Reads the file and invokes the given consumer for each row result.
      Parameters:
      consumer - Callback to receive parsed and validated row results
    • readStrict

      public void readStrict(Consumer<T> consumer)
      Reads the file and invokes the given consumer only for successfully parsed rows. If any row fails validation or mapping, a ReadAbortException is thrown immediately.
      Parameters:
      consumer - Callback to receive successfully parsed row data
      Throws:
      ReadAbortException - if any row fails validation or mapping
    • readAsStream

      public abstract Stream<ReadResult<T>> readAsStream()
      Reads the file and returns a lazy stream of row results.

      Important: The returned stream holds file and thread resources. Always use try-with-resources to ensure proper cleanup:

      
       try (Stream<ReadResult<T>> stream = handler.readAsStream()) {
           stream.forEach(result -> ...);
       }
       
      Returns:
      A stream of parsed and validated row results
    • validateIfNeeded

      protected boolean validateIfNeeded(T instance, List<String> messages)
      Validates the given instance using Bean Validation (if a validator is configured).
      Parameters:
      instance - The object to validate
      messages - A mutable list to collect violation messages
      Returns:
      true if valid or no validator is configured, false if violations exist
    • resolveColumnIndices

      protected int[] resolveColumnIndices(int columnCount, IntFunction<String> headerNameFn, IntUnaryOperator columnIndexFn, List<String> headerNames, String errorPrefix)
      Resolves column indices based on headerName, columnIndex, or positional order.
      Parameters:
      columnCount - number of columns to resolve
      headerNameFn - function to get headerName for column i (may return null)
      columnIndexFn - function to get explicit columnIndex for column i (-1 if not set)
      headerNames - the header names from the file
      errorPrefix - prefix for error messages (e.g., "sheet" or "CSV")
      Returns:
      resolved index array
    • mapColumn

      protected boolean mapColumn(BiConsumer<T,CellData> setter, T instance, CellData cellData, int columnIndex, List<String> headerNames, List<String> messages)
      Maps a single column value to the instance, handling exceptions.
      Parameters:
      setter - The setter to apply
      instance - The target object
      cellData - The cell data to set
      columnIndex - The column index (for error reporting)
      headerNames - The header names (for error reporting)
      messages - A mutable list to collect error messages
      Returns:
      true if mapping succeeded, false if an exception occurred
    • mapColumn

      protected boolean mapColumn(ReadColumn<T> column, T instance, CellData cellData, int columnIndex, List<String> headerNames, List<String> messages)
      Maps a single column value to the instance, with required-field validation.
      Parameters:
      column - The column definition (includes required flag)
      instance - The target object
      cellData - The cell data to set
      columnIndex - The column index (for error reporting)
      headerNames - The header names (for error reporting)
      messages - A mutable list to collect error messages
      Returns:
      true if mapping succeeded, false if an error occurred
    • mapWithRowMapper

      protected ReadResult<T> mapWithRowMapper(RowData rowData)
      Maps a row using the row mapper function (mapping mode). Catches exceptions from the mapper and wraps them in a failed ReadResult.
      Parameters:
      rowData - The row data to map
      Returns:
      A ReadResult containing the mapped instance or error messages