Skip to content

Commit 4307c54

Browse files
committed
Replace uniVocity CSV library with jackson-csv #702
Replace uniVocity CSV library with jackson-csv #702
1 parent 82c187c commit 4307c54

File tree

14 files changed

+120
-46
lines changed

14 files changed

+120
-46
lines changed

core/pom.xml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,8 @@
6363
<artifactId>jackson-dataformat-yaml</artifactId>
6464
</dependency>
6565
<dependency>
66-
<groupId>com.univocity</groupId>
67-
<artifactId>univocity-parsers</artifactId>
68-
</dependency>
69-
<dependency>
70-
<groupId>com.google.code.gson</groupId>
71-
<artifactId>gson</artifactId>
66+
<groupId>com.fasterxml.jackson.dataformat</groupId>
67+
<artifactId>jackson-dataformat-csv</artifactId>
7268
</dependency>
7369
<dependency>
7470
<groupId>org.apache.kafka</groupId>

core/src/main/java/org/jsmart/zerocode/core/db/DbCsvLoader.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,21 @@
1010

1111
import org.apache.commons.dbutils.QueryRunner;
1212
import org.apache.commons.lang3.StringUtils;
13+
import org.jsmart.zerocode.core.di.provider.CsvParserProvider;
1314
import org.slf4j.Logger;
1415
import org.slf4j.LoggerFactory;
1516

16-
import com.univocity.parsers.csv.CsvParser;
17+
1718

1819
/**
1920
* Data loading in the database from a CSV external source
2021
*/
2122
class DbCsvLoader {
2223
private static final Logger LOGGER = LoggerFactory.getLogger(DbCsvLoader.class);
2324
private Connection conn;
24-
private CsvParser csvParser;
25+
private CsvParserProvider csvParser;
2526

26-
public DbCsvLoader(Connection conn, CsvParser csvParser) {
27+
public DbCsvLoader(Connection conn, CsvParserProvider csvParser) {
2728
this.conn = conn;
2829
this.csvParser = csvParser;
2930
}

core/src/main/java/org/jsmart/zerocode/core/db/DbSqlExecutor.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package org.jsmart.zerocode.core.db;
22

33
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import com.fasterxml.jackson.dataformat.csv.CsvParser;
45
import com.google.inject.Inject;
56
import com.google.inject.name.Named;
6-
import com.univocity.parsers.csv.CsvParser;
7+
78

89
import org.apache.commons.dbutils.DbUtils;
10+
import org.jsmart.zerocode.core.di.provider.CsvParserProvider;
911
import org.slf4j.Logger;
1012
import org.slf4j.LoggerFactory;
1113
import java.sql.Connection;
@@ -36,7 +38,7 @@ public class DbSqlExecutor {
3638
@Named("db.driver.password") private String password;
3739

3840
@Inject
39-
private CsvParser csvParser;
41+
private CsvParserProvider csvParser;
4042

4143
/**
4244
* The LOADCSV operation inserts the content of a CSV file into a table,

core/src/main/java/org/jsmart/zerocode/core/di/module/CsvParserModule.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
import com.google.inject.Binder;
44
import com.google.inject.Module;
5-
import com.univocity.parsers.csv.CsvParser;
65
import jakarta.inject.Singleton;
6+
import org.jsmart.zerocode.core.di.provider.CsvParserInterface;
77
import org.jsmart.zerocode.core.di.provider.CsvParserProvider;
88

99
public class CsvParserModule implements Module {
1010

1111
@Override
1212
public void configure(Binder binder) {
13-
binder.bind(CsvParser.class).toProvider(CsvParserProvider.class).in(Singleton.class);
13+
binder.bind(CsvParserInterface.class).toProvider(CsvParserProvider.class).in(Singleton.class);
1414
}
1515
}
1616

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.jsmart.zerocode.core.di.provider;
2+
3+
import java.io.IOException;
4+
import java.io.InputStream;
5+
import java.util.List;
6+
7+
/**
8+
* Defines a contract for parsing a single line of CSV data into a string array.
9+
* Implementations should handle CSV lines with a specified format, such as
10+
* comma-separated fields with optional quoting and escaping.
11+
*/
12+
public interface CsvParserInterface {
13+
/**
14+
* Parses a single line of CSV data into an array of fields.
15+
*
16+
* @param line the CSV line to parse, which may include quoted fields and escaped characters
17+
* @return an array of strings representing the parsed fields; may be empty if the line is invalid
18+
* @throws IOException if an error occurs during parsing, such as malformed CSV data
19+
*/
20+
String[] parseLine(final String line) throws IOException;
21+
}
Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,61 @@
11
package org.jsmart.zerocode.core.di.provider;
22

3-
import com.univocity.parsers.csv.CsvParser;
4-
import com.univocity.parsers.csv.CsvParserSettings;
3+
4+
import com.fasterxml.jackson.databind.ObjectReader;
5+
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
6+
import com.fasterxml.jackson.dataformat.csv.CsvParser;
7+
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
58
import jakarta.inject.Provider;
9+
import org.apache.commons.lang3.StringUtils;
10+
import org.slf4j.Logger;
11+
import org.slf4j.LoggerFactory;
12+
13+
import java.io.IOException;
614

7-
public class CsvParserProvider implements Provider<CsvParser> {
15+
public class CsvParserProvider implements Provider<JacksonCsvParserAdapter> {
16+
private static final Logger logger = LoggerFactory.getLogger(CsvParserProvider.class);
17+
private static final JacksonCsvParserAdapter instance;
818
public static final String LINE_SEPARATOR = "\n";
19+
private static final String CARRIAGE_RETURN = "\r";
20+
21+
static {
22+
final CsvSchema schema = createCsvSchema();
23+
final ObjectReader mapper = new CsvMapper()
24+
.enable(CsvParser.Feature.TRIM_SPACES)
25+
.readerFor(String[].class)
26+
.with(schema);
27+
instance = new JacksonCsvParserAdapter(mapper);
28+
}
929

1030
@Override
11-
public CsvParser get() {
12-
CsvParserSettings settings = createCsvSettings();
13-
return new CsvParser(settings);
31+
public JacksonCsvParserAdapter get() {
32+
return instance;
33+
}
34+
35+
public String[] parseLine(final String line) {
36+
try {
37+
return instance.parseLine(sanitizeLine(line));
38+
} catch (final IOException e) {
39+
logger.warn("Failed to parse line: {}", line, e);
40+
return new String[0];
41+
}
42+
}
43+
44+
private String sanitizeLine(final String line) {
45+
if (StringUtils.isNotBlank(line) && !line.contains(CARRIAGE_RETURN)) {
46+
return line;
47+
}
48+
return line.replace(CARRIAGE_RETURN, StringUtils.EMPTY);
1449
}
1550

16-
private CsvParserSettings createCsvSettings() {
17-
CsvParserSettings settings = new CsvParserSettings();
18-
settings.getFormat().setDelimiter(",");
19-
settings.getFormat().setQuote('\'');
20-
settings.getFormat().setQuoteEscape('\'');
21-
settings.setEmptyValue("");
22-
settings.getFormat().setLineSeparator("\n");
23-
settings.setAutoConfigurationEnabled(false);
24-
return settings;
51+
private static CsvSchema createCsvSchema() {
52+
return CsvSchema.builder()
53+
.setColumnSeparator(',')
54+
.setQuoteChar('\'')
55+
.setEscapeChar('\'')
56+
.setNullValue("")
57+
.setLineSeparator(LINE_SEPARATOR)
58+
.build();
2559
}
2660

2761
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.jsmart.zerocode.core.di.provider;
2+
3+
import com.fasterxml.jackson.databind.ObjectReader;
4+
5+
import java.io.IOException;
6+
import java.io.StringReader;
7+
8+
public class JacksonCsvParserAdapter implements CsvParserInterface {
9+
10+
private final ObjectReader mapper;
11+
public JacksonCsvParserAdapter(final ObjectReader mapper) {
12+
this.mapper = mapper;
13+
}
14+
@Override
15+
public String[] parseLine(final String line) throws IOException {
16+
return mapper.readValue(new StringReader(line));
17+
}
18+
}

core/src/main/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeParameterizedProcessorImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import com.fasterxml.jackson.databind.ObjectMapper;
44
import com.google.inject.Inject;
55
import com.google.inject.Singleton;
6-
import com.univocity.parsers.csv.CsvParser;
76
import org.apache.commons.collections4.CollectionUtils;
87
import org.apache.commons.text.StringSubstitutor;
8+
import org.jsmart.zerocode.core.di.provider.CsvParserProvider;
99
import org.jsmart.zerocode.core.domain.ScenarioSpec;
1010
import org.jsmart.zerocode.core.utils.TokenUtils;
1111
import org.slf4j.Logger;
@@ -55,10 +55,10 @@ public class ZeroCodeParameterizedProcessorImpl implements ZeroCodeParameterized
5555

5656
private final ObjectMapper objectMapper;
5757

58-
private final CsvParser csvParser;
58+
private final CsvParserProvider csvParser;
5959

6060
@Inject
61-
public ZeroCodeParameterizedProcessorImpl(ObjectMapper objectMapper, CsvParser csvParser) {
61+
public ZeroCodeParameterizedProcessorImpl(ObjectMapper objectMapper, CsvParserProvider csvParser) {
6262
this.objectMapper = objectMapper;
6363
this.csvParser = csvParser;
6464
}

core/src/main/java/org/jsmart/zerocode/core/runner/ZeroCodeMultiStepsScenarioRunnerImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
import com.google.inject.Inject;
77
import com.google.inject.Singleton;
88
import com.google.inject.name.Named;
9-
import com.univocity.parsers.csv.CsvParser;
9+
1010
import static java.util.Optional.ofNullable;
1111
import static org.apache.commons.collections4.CollectionUtils.isEmpty;
1212
import static org.jsmart.zerocode.core.constants.ZerocodeConstants.KAFKA_TOPIC;
1313

14+
import org.jsmart.zerocode.core.di.provider.CsvParserProvider;
1415
import org.jsmart.zerocode.core.domain.Parameterized;
1516
import org.jsmart.zerocode.core.domain.ScenarioSpec;
1617
import org.jsmart.zerocode.core.domain.Step;
@@ -72,8 +73,7 @@ public class ZeroCodeMultiStepsScenarioRunnerImpl implements ZeroCodeMultiStepsS
7273
private ApiServiceExecutor apiExecutor;
7374

7475
@Inject
75-
private CsvParser csvParser;
76-
76+
private CsvParserProvider csvParser;
7777
@Inject
7878
private ApiTypeUtils apiTypeUtils;
7979

core/src/test/java/org/jsmart/zerocode/core/db/DbCsvLoaderTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,21 @@
99
import java.util.List;
1010
import java.util.Map;
1111

12+
import org.jsmart.zerocode.core.di.provider.CsvParserProvider;
1213
import org.jukito.JukitoRunner;
1314
import org.junit.Test;
1415
import org.junit.runner.RunWith;
1516

1617
import com.google.inject.Inject;
17-
import com.univocity.parsers.csv.CsvParser;
18+
1819

1920
@RunWith(JukitoRunner.class)
2021
public class DbCsvLoaderTest extends DbTestBase{
2122

2223
private DbCsvLoader loader;
2324

2425
@Inject
25-
CsvParser csvParser;
26+
CsvParserProvider csvParser;
2627

2728
@Override
2829
public void setUp() throws SQLException {

0 commit comments

Comments
 (0)