Skip to content

Commit

Permalink
Merge pull request #12 from 42BV/feature/invalid-columns-fix
Browse files Browse the repository at this point in the history
Include error when a row has an invalid amount of columns
  • Loading branch information
jeroenvs authored Nov 14, 2023
2 parents 0a2d065 + a631fb0 commit 9ee3cac
Show file tree
Hide file tree
Showing 22 changed files with 351 additions and 322 deletions.
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
<java.version>17</java.version>

<!-- Dependencies -->
<spring.boot.version>3.0.5</spring.boot.version>
<spring.boot.version>3.1.5</spring.boot.version>
</properties>

<dependencyManagement>
Expand Down Expand Up @@ -73,7 +73,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
<version>32.1.3-jre</version>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
Expand Down Expand Up @@ -202,7 +202,7 @@
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>8.1.2</version>
<version>8.4.2</version>
<configuration>
<failBuildOnAnyVulnerability>true</failBuildOnAnyVulnerability>
<skipProvidedScope>true</skipProvidedScope>
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/nl/_42/boot/csv/CsvHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,36 @@

/**
* Handler of a specific CSV type.
*
* @param <T> the bean class
*/
public interface CsvHandler<T> {

/**
* Retrieve the CSV type name.
*
* @return the type name
*/
String getType();

/**
* Retrieve the target bean class.
*
* @return the target bean class
*/
Class<T> getBeanClass();

/**
* Process a CSV client, containing the data.
*
* @param client the CSV client
* @return the CSV result
*/
CsvResult handle(CsvClient<T> client);

/**
* Describe this CSV type, can be shown for usage.
*
* @param document the CSV description for this type
*/
default void describe(CsvDocument document) {
Expand Down
12 changes: 9 additions & 3 deletions src/main/java/nl/_42/boot/csv/CsvMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
* or dynamic based on a prefix or variable tail.
* <br>
* Only use this mapper when static mapping is not possible.
*
* @param <T> the target type
*/
public class CsvMapper<T> implements Function<Row, T> {
Expand Down Expand Up @@ -68,6 +69,7 @@ private Builder(Supplier<T> constructor, Header header) {

/**
* Expected the next column to have a certain name.
*
* @param expected the expected name
* @param consumer the handler
* @return this builder
Expand All @@ -79,6 +81,7 @@ public Builder<T> add(String expected, BiConsumer<String, T> consumer) {

/**
* Register consumer when header is present.
*
* @param expected the expected name
* @param consumer the handler
* @return this builder
Expand All @@ -95,7 +98,7 @@ private void checkHeader(String expected) {
String name = getName(index);
if (!Objects.equals(expected, name)) {
throw new IllegalArgumentException(
format("Expected header '%s' at index %d but got '%s'", expected, index, name)
format("Expected header '%s' at index %d but got '%s'", expected, index, name)
);
}
}
Expand Down Expand Up @@ -126,15 +129,16 @@ private BiConsumer<String, T> wrap(BiConsumer<String, T> consumer, int index) {
consumer.accept(key, value);
} catch (RuntimeException rte) {
throw new IllegalStateException(
format("Could not map column '%s' at index %d: %s", name, index, rte.getMessage()),
rte
format("Could not map column '%s' at index %d: %s", name, index, rte.getMessage()),
rte
);
}
};
}

/**
* Register all next columns that start with the prefix, if any.
*
* @param prefix the prefix
* @param mapper the function producing a handler for each column
* @return this builder
Expand All @@ -151,6 +155,7 @@ public Builder<T> addStartsWith(String prefix, Function<String, BiConsumer<Strin

/**
* Register all remaining columns, if any.
*
* @param mapper the function producing a handler for each column
* @return this builder
*/
Expand All @@ -164,6 +169,7 @@ public Builder<T> addRemainder(Function<String, BiConsumer<String, T>> mapper) {

/**
* Use a different formatter for parsing headers and values.
*
* @param formatter the formatter
* @return this builder
*/
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/nl/_42/boot/csv/CsvResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static CsvResult error(Throwable throwable) {

public CsvResult error(int rowNumber, String message) {
CsvError error = errors.stream().filter(e -> e.rowNumber == rowNumber)
.findFirst().orElseGet(() -> addError(rowNumber));
.findFirst().orElseGet(() -> addError(rowNumber));

error.addMessage(message);
return this;
Expand Down
17 changes: 12 additions & 5 deletions src/main/java/nl/_42/boot/csv/CsvService.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public CsvService(CsvProperties properties) {

/**
* Retrieve all known CSV types and properties.
*
* @return the parameters
*/
public CsvParameters getParameters() {
Expand All @@ -46,6 +47,7 @@ public CsvParameters getParameters() {

/**
* Retrieve all CSV types.
*
* @return the types
*/
public Collection<String> getTypes() {
Expand All @@ -56,13 +58,14 @@ public Collection<String> getTypes() {
}

return types.stream()
.filter(handlers::containsKey)
.collect(Collectors.toList());
.filter(handlers::containsKey)
.collect(Collectors.toList());
}

/**
* Process a CSV, based on default properties.
* @param is the CSV content
*
* @param is the CSV content
* @param type the CSV type
* @return the result
*/
Expand All @@ -72,8 +75,9 @@ public CsvResult load(InputStream is, String type) {

/**
* Process a CSV.
* @param is the CSV content
* @param type the CSV type
*
* @param is the CSV content
* @param type the CSV type
* @param properties the properties
* @return the result
*/
Expand All @@ -84,6 +88,7 @@ public CsvResult load(InputStream is, String type, CsvProperties properties) {

/**
* Retrieve the documentation of a CSV handler.
*
* @param type the CSV type
* @return the documentation
*/
Expand All @@ -96,6 +101,7 @@ public CsvDocument getDocument(String type) {

/**
* Validate the CSV handler based on its documentation.
*
* @param type the CSV type
* @return the result
*/
Expand Down Expand Up @@ -150,6 +156,7 @@ private InputStreamReader getReader(InputStream is) throws IOException {

/**
* Register all known handlers.
*
* @param handlers the handlers, if any
*/
@Autowired(required = false)
Expand Down
24 changes: 7 additions & 17 deletions src/main/java/nl/_42/boot/csv/CsvTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,31 +32,21 @@ public <T, R> CsvResult read(Supplier<T> supplier, Function<T, R> transformer, C
private <T, R> boolean next(Supplier<T> supplier, Function<T, R> transformer, Consumer<R> consumer, int rowNumber) {
boolean found = false;

T row = get(supplier);
if (row != null) {
try {
try {
T row = supplier.get();
if (row != null) {
R value = transformer.apply(row);
consumer.accept(value);
result.success();
} catch (RuntimeException rte) {
log.error("Could not handle CSV row " + rowNumber, rte);
result.error(rowNumber, rte.getMessage());
} finally {
found = true;
}
} catch (RuntimeException rte) {
log.error("Could not handle CSV row " + rowNumber, rte);
result.error(rowNumber, rte.getMessage());
found = true;
}

return found;
}

private <T> T get(Supplier<T> supplier) {
T row = null;
try {
row = supplier.get();
} catch (RuntimeException npe) {
log.error("Could not handle CSV", npe);
}
return row;
}

}
1 change: 0 additions & 1 deletion src/main/java/nl/_42/boot/csv/bootstrap/CsvLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ public class CsvLoader {
* Load all CSV files inside a classpath location. During execution
* the loader will scan for files matching the defined CSV types, e.g.
* 'PERSON' expects a 'person.csv'.
*
* Whenever a matching file is found it is loaded automatically.
*
* @param location the base directory on the classpath
Expand Down
Loading

0 comments on commit 9ee3cac

Please sign in to comment.