Skip to content

Commit 81f5c9e

Browse files
committed
Support Lambda-style configuration in FlatFileItem builders
Signed-off-by: Daeho Kwon <[email protected]>
1 parent d7e13fb commit 81f5c9e

File tree

4 files changed

+209
-68
lines changed

4 files changed

+209
-68
lines changed

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/FlatFileItemReaderBuilder.java

Lines changed: 62 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2023 the original author or authors.
2+
* Copyright 2016-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
2525
import java.util.List;
2626
import java.util.Map;
2727
import java.util.Set;
28+
import java.util.function.Consumer;
2829

2930
import org.apache.commons.logging.Log;
3031
import org.apache.commons.logging.LogFactory;
@@ -58,6 +59,7 @@
5859
* @author Glenn Renfro
5960
* @author Mahmoud Ben Hassine
6061
* @author Drummond Dawson
62+
* @author Daeho Kwon
6163
* @since 4.0
6264
* @see FlatFileItemReader
6365
*/
@@ -87,9 +89,9 @@ public class FlatFileItemReaderBuilder<T> {
8789

8890
private LineTokenizer lineTokenizer;
8991

90-
private DelimitedBuilder<T> delimitedBuilder;
92+
private DelimitedSpec<T> delimitedSpec;
9193

92-
private FixedLengthBuilder<T> fixedLengthBuilder;
94+
private FixedLengthSpec<T> fixedLengthSpec;
9395

9496
private Class<T> targetType;
9597

@@ -304,30 +306,56 @@ public FlatFileItemReaderBuilder<T> lineTokenizer(LineTokenizer tokenizer) {
304306
}
305307

306308
/**
307-
* Returns an instance of a {@link DelimitedBuilder} for building a
309+
* Returns an instance of a {@link DelimitedSpec} for building a
308310
* {@link DelimitedLineTokenizer}. The {@link DelimitedLineTokenizer} configured by
309311
* this builder will only be used if one is not explicitly configured via
310312
* {@link FlatFileItemReaderBuilder#lineTokenizer}
311-
* @return a {@link DelimitedBuilder}
313+
* @return a {@link DelimitedSpec}
312314
*
313315
*/
314-
public DelimitedBuilder<T> delimited() {
315-
this.delimitedBuilder = new DelimitedBuilder<>(this);
316-
updateTokenizerValidation(this.delimitedBuilder, 1);
317-
return this.delimitedBuilder;
316+
public DelimitedSpec<T> delimited() {
317+
this.delimitedSpec = new DelimitedSpec<>(this);
318+
updateTokenizerValidation(this.delimitedSpec, 1);
319+
return this.delimitedSpec;
318320
}
319321

320322
/**
321-
* Returns an instance of a {@link FixedLengthBuilder} for building a
323+
* Configure a {@link DelimitedSpec} using a lambda.
324+
* @param consumer the spec to configure
325+
* @return the current builder instance
326+
*/
327+
public FlatFileItemReaderBuilder<T> delimited(Consumer<DelimitedSpec<T>> consumer) {
328+
DelimitedSpec<T> builder = new DelimitedSpec<>(this);
329+
consumer.accept(builder);
330+
this.delimitedSpec = builder;
331+
updateTokenizerValidation(this.delimitedSpec, 1);
332+
return this;
333+
}
334+
335+
/**
336+
* Returns an instance of a {@link FixedLengthSpec} for building a
322337
* {@link FixedLengthTokenizer}. The {@link FixedLengthTokenizer} configured by this
323338
* builder will only be used if the {@link FlatFileItemReaderBuilder#lineTokenizer}
324339
* has not been configured.
325-
* @return a {@link FixedLengthBuilder}
340+
* @return a {@link FixedLengthSpec}
326341
*/
327-
public FixedLengthBuilder<T> fixedLength() {
328-
this.fixedLengthBuilder = new FixedLengthBuilder<>(this);
329-
updateTokenizerValidation(this.fixedLengthBuilder, 2);
330-
return this.fixedLengthBuilder;
342+
public FixedLengthSpec<T> fixedLength() {
343+
this.fixedLengthSpec = new FixedLengthSpec<>(this);
344+
updateTokenizerValidation(this.fixedLengthSpec, 2);
345+
return this.fixedLengthSpec;
346+
}
347+
348+
/**
349+
* Configure a {@link FixedLengthSpec} using a lambda.
350+
* @param consumer the spec to configure
351+
* @return the current builder instance
352+
*/
353+
public FlatFileItemReaderBuilder<T> fixedLength(Consumer<FixedLengthSpec<T>> consumer) {
354+
FixedLengthSpec<T> builder = new FixedLengthSpec<>(this);
355+
consumer.accept(builder);
356+
this.fixedLengthSpec = builder;
357+
updateTokenizerValidation(this.fixedLengthSpec, 2);
358+
return this;
331359
}
332360

333361
/**
@@ -449,11 +477,11 @@ public FlatFileItemReader<T> build() {
449477
if (this.lineTokenizer != null) {
450478
lineMapper.setLineTokenizer(this.lineTokenizer);
451479
}
452-
else if (this.fixedLengthBuilder != null) {
453-
lineMapper.setLineTokenizer(this.fixedLengthBuilder.build());
480+
else if (this.fixedLengthSpec != null) {
481+
lineMapper.setLineTokenizer(this.fixedLengthSpec.build());
454482
}
455-
else if (this.delimitedBuilder != null) {
456-
lineMapper.setLineTokenizer(this.delimitedBuilder.build());
483+
else if (this.delimitedSpec != null) {
484+
lineMapper.setLineTokenizer(this.delimitedSpec.build());
457485
}
458486
else {
459487
throw new IllegalStateException("No LineTokenizer implementation was provided.");
@@ -519,7 +547,7 @@ private void updateTokenizerValidation(Object tokenizer, int index) {
519547
*
520548
* @param <T> the type of the parent {@link FlatFileItemReaderBuilder}
521549
*/
522-
public static class DelimitedBuilder<T> {
550+
public static class DelimitedSpec<T> {
523551

524552
private final FlatFileItemReaderBuilder<T> parent;
525553

@@ -535,7 +563,7 @@ public static class DelimitedBuilder<T> {
535563

536564
private boolean strict = true;
537565

538-
protected DelimitedBuilder(FlatFileItemReaderBuilder<T> parent) {
566+
protected DelimitedSpec(FlatFileItemReaderBuilder<T> parent) {
539567
this.parent = parent;
540568
}
541569

@@ -545,7 +573,7 @@ protected DelimitedBuilder(FlatFileItemReaderBuilder<T> parent) {
545573
* @return The instance of the builder for chaining.
546574
* @see DelimitedLineTokenizer#setDelimiter(String)
547575
*/
548-
public DelimitedBuilder<T> delimiter(String delimiter) {
576+
public DelimitedSpec<T> delimiter(String delimiter) {
549577
this.delimiter = delimiter;
550578
return this;
551579
}
@@ -556,7 +584,7 @@ public DelimitedBuilder<T> delimiter(String delimiter) {
556584
* @return The instance of the builder for chaining.
557585
* @see DelimitedLineTokenizer#setQuoteCharacter(char)
558586
*/
559-
public DelimitedBuilder<T> quoteCharacter(char quoteCharacter) {
587+
public DelimitedSpec<T> quoteCharacter(char quoteCharacter) {
560588
this.quoteCharacter = quoteCharacter;
561589
return this;
562590
}
@@ -567,7 +595,7 @@ public DelimitedBuilder<T> quoteCharacter(char quoteCharacter) {
567595
* @return The instance of the builder for chaining.
568596
* @see DelimitedLineTokenizer#setIncludedFields(int[])
569597
*/
570-
public DelimitedBuilder<T> includedFields(Integer... fields) {
598+
public DelimitedSpec<T> includedFields(Integer... fields) {
571599
this.includedFields.addAll(Arrays.asList(fields));
572600
return this;
573601
}
@@ -578,7 +606,7 @@ public DelimitedBuilder<T> includedFields(Integer... fields) {
578606
* @return The instance of the builder for chaining.
579607
* @see DelimitedLineTokenizer#setIncludedFields(int[])
580608
*/
581-
public DelimitedBuilder<T> addIncludedField(int field) {
609+
public DelimitedSpec<T> addIncludedField(int field) {
582610
this.includedFields.add(field);
583611
return this;
584612
}
@@ -592,7 +620,7 @@ public DelimitedBuilder<T> addIncludedField(int field) {
592620
* @return The instance of the builder for chaining.
593621
* @see DelimitedLineTokenizer#setFieldSetFactory(FieldSetFactory)
594622
*/
595-
public DelimitedBuilder<T> fieldSetFactory(FieldSetFactory fieldSetFactory) {
623+
public DelimitedSpec<T> fieldSetFactory(FieldSetFactory fieldSetFactory) {
596624
this.fieldSetFactory = fieldSetFactory;
597625
return this;
598626
}
@@ -618,7 +646,7 @@ public FlatFileItemReaderBuilder<T> names(String... names) {
618646
* @since 5.1
619647
* @param strict the strict flag to set
620648
*/
621-
public DelimitedBuilder<T> strict(boolean strict) {
649+
public DelimitedSpec<T> strict(boolean strict) {
622650
this.strict = strict;
623651
return this;
624652
}
@@ -677,7 +705,7 @@ public DelimitedLineTokenizer build() {
677705
*
678706
* @param <T> the type of the parent {@link FlatFileItemReaderBuilder}
679707
*/
680-
public static class FixedLengthBuilder<T> {
708+
public static class FixedLengthSpec<T> {
681709

682710
private final FlatFileItemReaderBuilder<T> parent;
683711

@@ -689,7 +717,7 @@ public static class FixedLengthBuilder<T> {
689717

690718
private FieldSetFactory fieldSetFactory = new DefaultFieldSetFactory();
691719

692-
protected FixedLengthBuilder(FlatFileItemReaderBuilder<T> parent) {
720+
protected FixedLengthSpec(FlatFileItemReaderBuilder<T> parent) {
693721
this.parent = parent;
694722
}
695723

@@ -699,7 +727,7 @@ protected FixedLengthBuilder(FlatFileItemReaderBuilder<T> parent) {
699727
* @return This instance for chaining
700728
* @see FixedLengthTokenizer#setColumns(Range[])
701729
*/
702-
public FixedLengthBuilder<T> columns(Range... ranges) {
730+
public FixedLengthSpec<T> columns(Range... ranges) {
703731
this.ranges.addAll(Arrays.asList(ranges));
704732
return this;
705733
}
@@ -710,7 +738,7 @@ public FixedLengthBuilder<T> columns(Range... ranges) {
710738
* @return This instance for chaining
711739
* @see FixedLengthTokenizer#setColumns(Range[])
712740
*/
713-
public FixedLengthBuilder<T> addColumns(Range range) {
741+
public FixedLengthSpec<T> addColumns(Range range) {
714742
this.ranges.add(range);
715743
return this;
716744
}
@@ -722,7 +750,7 @@ public FixedLengthBuilder<T> addColumns(Range range) {
722750
* @return This instance for chaining
723751
* @see FixedLengthTokenizer#setColumns(Range[])
724752
*/
725-
public FixedLengthBuilder<T> addColumns(Range range, int index) {
753+
public FixedLengthSpec<T> addColumns(Range range, int index) {
726754
this.ranges.add(index, range);
727755
return this;
728756
}
@@ -745,7 +773,7 @@ public FlatFileItemReaderBuilder<T> names(String... names) {
745773
* @return This instance for chaining
746774
* @see FixedLengthTokenizer#setStrict(boolean)
747775
*/
748-
public FixedLengthBuilder<T> strict(boolean strict) {
776+
public FixedLengthSpec<T> strict(boolean strict) {
749777
this.strict = strict;
750778
return this;
751779
}
@@ -759,7 +787,7 @@ public FixedLengthBuilder<T> strict(boolean strict) {
759787
* @return The instance of the builder for chaining.
760788
* @see FixedLengthTokenizer#setFieldSetFactory(FieldSetFactory)
761789
*/
762-
public FixedLengthBuilder<T> fieldSetFactory(FieldSetFactory fieldSetFactory) {
790+
public FixedLengthSpec<T> fieldSetFactory(FieldSetFactory fieldSetFactory) {
763791
this.fieldSetFactory = fieldSetFactory;
764792
return this;
765793
}

0 commit comments

Comments
 (0)