Skip to content

Commit e8cb135

Browse files
committedJan 28, 2025·
Replaced openCSV by fastCSV
1 parent 22627c7 commit e8cb135

11 files changed

+4031
-4011
lines changed
 

‎CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
- Implemented 2025 updates of solid tumor rules. (#147)
66
- Updated HematoDB data with latest data from SEER API.
7+
- Replaced OpenCSV library by FastCSV.
8+
- Changed minimum Java language from Java 8 to Java 11.
79

810
**Changes in version 1.36**
911

‎build.gradle

+9-9
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ plugins {
44
id 'java-library'
55
id 'checkstyle'
66
id 'jacoco'
7-
id 'com.github.spotbugs' version '6.0.23'
7+
id 'com.github.spotbugs' version '6.1.3'
88
id 'maven-publish'
99
id 'signing'
1010
id 'io.github.gradle-nexus.publish-plugin' version '2.0.0' // publish to Maven Central
11-
id 'com.github.ben-manes.versions' version '0.51.0' // check for out-of-date dependencies (run 'dependencyUpdates' manually)
12-
id 'org.sonatype.gradle.plugins.scan' version '2.8.3' // scan for vulnerabilities
13-
id 'org.sonarqube' version '5.1.0.4882' // sonarQube analysis
11+
id 'com.github.ben-manes.versions' version '0.52.0' // check for out-of-date dependencies (run 'dependencyUpdates' manually)
12+
id 'org.sonatype.gradle.plugins.scan' version '3.0.0' // scan for vulnerabilities
13+
id 'org.sonarqube' version '6.0.1.5171' // sonarQube analysis
1414
}
1515

1616
group = 'com.imsweb'
@@ -25,11 +25,11 @@ repositories {
2525

2626
dependencies {
2727
implementation 'org.apache.commons:commons-lang3:3.17.0'
28-
implementation 'com.opencsv:opencsv:5.9'
28+
implementation 'de.siegmar:fastcsv:3.4.0'
2929

3030
testImplementation 'junit:junit:4.13.2'
31-
testImplementation 'com.imsweb:seerapi-client-java:5.6'
32-
testImplementation 'com.imsweb:data-generator:1.33'
31+
testImplementation 'com.imsweb:seerapi-client-java:5.7'
32+
testImplementation 'com.imsweb:data-generator:2.0'
3333
}
3434

3535
// enforce UTF-8, display the compilation warnings
@@ -45,8 +45,8 @@ tasks.withType(Javadoc).configureEach {
4545

4646
// generate javadoc and sources (required by Nexus)
4747
java {
48-
sourceCompatibility = JavaVersion.VERSION_1_8
49-
targetCompatibility = JavaVersion.VERSION_1_8
48+
sourceCompatibility = JavaVersion.VERSION_11
49+
targetCompatibility = JavaVersion.VERSION_11
5050

5151
withJavadocJar()
5252
withSourcesJar()

‎src/main/java/com/imsweb/mph/DefaultHematoDataProvider.java

+54-44
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.io.IOException;
77
import java.io.InputStream;
88
import java.io.InputStreamReader;
9+
import java.io.Reader;
910
import java.nio.charset.StandardCharsets;
1011
import java.text.ParseException;
1112
import java.text.SimpleDateFormat;
@@ -19,8 +20,8 @@
1920

2021
import org.apache.commons.lang3.StringUtils;
2122

22-
import com.opencsv.CSVReaderBuilder;
23-
import com.opencsv.exceptions.CsvException;
23+
import de.siegmar.fastcsv.reader.CsvReader;
24+
import de.siegmar.fastcsv.reader.NamedCsvRecord;
2425

2526
import com.imsweb.mph.internal.HematoDTO;
2627

@@ -30,72 +31,81 @@
3031
*/
3132
public class DefaultHematoDataProvider implements HematoDataProvider {
3233

33-
private Map<String, List<HematoDTO>> _samePrimaryDto;
34-
private Map<String, List<HematoDTO>> _transformToDto;
35-
private Map<String, List<HematoDTO>> _transformFromDto;
34+
private final Map<String, List<HematoDTO>> _samePrimaryDto;
35+
private final Map<String, List<HematoDTO>> _transformToDto;
36+
private final Map<String, List<HematoDTO>> _transformFromDto;
3637

3738
public DefaultHematoDataProvider() {
39+
3840
_samePrimaryDto = new HashMap<>();
3941
try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("Hematopoietic2010SamePrimaryPairs.csv")) {
4042
if (is == null)
4143
throw new IllegalStateException("Unable to get Hematopoietic2010SamePrimaryPairs.csv");
42-
for (String[] row : new CSVReaderBuilder(new InputStreamReader(is, StandardCharsets.US_ASCII)).withSkipLines(1).build().readAll()) {
43-
Short validStartYear = StringUtils.isNotBlank(row[1]) ? Short.valueOf(row[1]) : null;
44-
Short validEndYear = StringUtils.isNotBlank(row[2]) ? Short.valueOf(row[2]) : null;
45-
Short startYear = StringUtils.isNotBlank(row[3]) ? Short.valueOf(row[3]) : null;
46-
Short endYear = StringUtils.isNotBlank(row[4]) ? Short.valueOf(row[4]) : null;
47-
if (_samePrimaryDto.containsKey(row[0]))
48-
_samePrimaryDto.get(row[0]).add(new HematoDTO(validStartYear, validEndYear, startYear, endYear, row[5]));
49-
else {
50-
List<HematoDTO> list = new ArrayList<>();
51-
list.add(new HematoDTO(validStartYear, validEndYear, startYear, endYear, row[5]));
52-
_samePrimaryDto.put(row[0], list);
53-
}
44+
try (Reader reader = new InputStreamReader(is, StandardCharsets.US_ASCII); CsvReader<NamedCsvRecord> csvReader = CsvReader.builder().ofNamedCsvRecord(reader)) {
45+
csvReader.stream().forEach(line -> {
46+
Short validStartYear = StringUtils.isNotBlank(line.getField(1)) ? Short.valueOf(line.getField(1)) : null;
47+
Short validEndYear = StringUtils.isNotBlank(line.getField(2)) ? Short.valueOf(line.getField(2)) : null;
48+
Short startYear = StringUtils.isNotBlank(line.getField(3)) ? Short.valueOf(line.getField(3)) : null;
49+
Short endYear = StringUtils.isNotBlank(line.getField(4)) ? Short.valueOf(line.getField(4)) : null;
50+
if (_samePrimaryDto.containsKey(line.getField(0)))
51+
_samePrimaryDto.get(line.getField(0)).add(new HematoDTO(validStartYear, validEndYear, startYear, endYear, line.getField(5)));
52+
else {
53+
List<HematoDTO> list = new ArrayList<>();
54+
list.add(new HematoDTO(validStartYear, validEndYear, startYear, endYear, line.getField(5)));
55+
_samePrimaryDto.put(line.getField(0), list);
56+
}
57+
});
5458
}
5559
}
56-
catch (CsvException | IOException e) {
60+
catch (IOException e) {
5761
throw new IllegalStateException(e);
5862
}
63+
5964
_transformToDto = new HashMap<>();
6065
try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("Hematopoietic2010TransformToPairs.csv")) {
6166
if (is == null)
6267
throw new IllegalStateException("Unable to get Hematopoietic2010TransformToPairs.csv");
63-
for (String[] row : new CSVReaderBuilder(new InputStreamReader(is, StandardCharsets.US_ASCII)).withSkipLines(1).build().readAll()) {
64-
Short validStartYear = StringUtils.isNotBlank(row[1]) ? Short.valueOf(row[1]) : null;
65-
Short validEndYear = StringUtils.isNotBlank(row[2]) ? Short.valueOf(row[2]) : null;
66-
Short startYear = StringUtils.isNotBlank(row[3]) ? Short.valueOf(row[3]) : null;
67-
Short endYear = StringUtils.isNotBlank(row[4]) ? Short.valueOf(row[4]) : null;
68-
if (_transformToDto.containsKey(row[0]))
69-
_transformToDto.get(row[0]).add(new HematoDTO(validStartYear, validEndYear, startYear, endYear, row[5]));
70-
else {
71-
List<HematoDTO> list = new ArrayList<>();
72-
list.add(new HematoDTO(validStartYear, validEndYear, startYear, endYear, row[5]));
73-
_transformToDto.put(row[0], list);
74-
}
68+
try (Reader reader = new InputStreamReader(is, StandardCharsets.US_ASCII); CsvReader<NamedCsvRecord> csvReader = CsvReader.builder().ofNamedCsvRecord(reader)) {
69+
csvReader.stream().forEach(line -> {
70+
Short validStartYear = StringUtils.isNotBlank(line.getField(1)) ? Short.valueOf(line.getField(1)) : null;
71+
Short validEndYear = StringUtils.isNotBlank(line.getField(2)) ? Short.valueOf(line.getField(2)) : null;
72+
Short startYear = StringUtils.isNotBlank(line.getField(3)) ? Short.valueOf(line.getField(3)) : null;
73+
Short endYear = StringUtils.isNotBlank(line.getField(4)) ? Short.valueOf(line.getField(4)) : null;
74+
if (_transformToDto.containsKey(line.getField(0)))
75+
_transformToDto.get(line.getField(0)).add(new HematoDTO(validStartYear, validEndYear, startYear, endYear, line.getField(5)));
76+
else {
77+
List<HematoDTO> list = new ArrayList<>();
78+
list.add(new HematoDTO(validStartYear, validEndYear, startYear, endYear, line.getField(5)));
79+
_transformToDto.put(line.getField(0), list);
80+
}
81+
});
7582
}
7683
}
77-
catch (CsvException | IOException e) {
84+
catch (IOException e) {
7885
throw new IllegalStateException(e);
7986
}
87+
8088
_transformFromDto = new HashMap<>();
8189
try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("Hematopoietic2010TransformFromPairs.csv")) {
8290
if (is == null)
8391
throw new IllegalStateException("Unable to get Hematopoietic2010TransformFromPairs.csv");
84-
for (String[] row : new CSVReaderBuilder(new InputStreamReader(is, StandardCharsets.US_ASCII)).withSkipLines(1).build().readAll()) {
85-
Short validStartYear = StringUtils.isNotBlank(row[1]) ? Short.valueOf(row[1]) : null;
86-
Short validEndYear = StringUtils.isNotBlank(row[2]) ? Short.valueOf(row[2]) : null;
87-
Short startYear = StringUtils.isNotBlank(row[3]) ? Short.valueOf(row[3]) : null;
88-
Short endYear = StringUtils.isNotBlank(row[4]) ? Short.valueOf(row[4]) : null;
89-
if (_transformFromDto.containsKey(row[0]))
90-
_transformFromDto.get(row[0]).add(new HematoDTO(validStartYear, validEndYear, startYear, endYear, row[5]));
91-
else {
92-
List<HematoDTO> list = new ArrayList<>();
93-
list.add(new HematoDTO(validStartYear, validEndYear, startYear, endYear, row[5]));
94-
_transformFromDto.put(row[0], list);
95-
}
92+
try (Reader reader = new InputStreamReader(is, StandardCharsets.US_ASCII); CsvReader<NamedCsvRecord> csvReader = CsvReader.builder().ofNamedCsvRecord(reader)) {
93+
csvReader.stream().forEach(line -> {
94+
Short validStartYear = StringUtils.isNotBlank(line.getField(1)) ? Short.valueOf(line.getField(1)) : null;
95+
Short validEndYear = StringUtils.isNotBlank(line.getField(2)) ? Short.valueOf(line.getField(2)) : null;
96+
Short startYear = StringUtils.isNotBlank(line.getField(3)) ? Short.valueOf(line.getField(3)) : null;
97+
Short endYear = StringUtils.isNotBlank(line.getField(4)) ? Short.valueOf(line.getField(4)) : null;
98+
if (_transformFromDto.containsKey(line.getField(0)))
99+
_transformFromDto.get(line.getField(0)).add(new HematoDTO(validStartYear, validEndYear, startYear, endYear, line.getField(5)));
100+
else {
101+
List<HematoDTO> list = new ArrayList<>();
102+
list.add(new HematoDTO(validStartYear, validEndYear, startYear, endYear, line.getField(5)));
103+
_transformFromDto.put(line.getField(0), list);
104+
}
105+
});
96106
}
97107
}
98-
catch (CsvException | IOException e) {
108+
catch (IOException e) {
99109
throw new IllegalStateException(e);
100110
}
101111

‎src/main/java/com/imsweb/mph/mpgroups/GroupUtility.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ public static List<Range<Integer>> computeRange(String rawValue, boolean isSite)
121121
}
122122
else {
123123
if (isSite)
124-
result.add(Range.between(Integer.parseInt(parts[0].trim().substring(1)), Integer.parseInt(parts[1].trim().substring(1))));
124+
result.add(Range.of(Integer.parseInt(parts[0].trim().substring(1)), Integer.parseInt(parts[1].trim().substring(1))));
125125
else
126-
result.add(Range.between(Integer.parseInt(parts[0].trim()), Integer.parseInt(parts[1].trim())));
126+
result.add(Range.of(Integer.parseInt(parts[0].trim()), Integer.parseInt(parts[1].trim())));
127127
}
128128
}
129129

‎src/main/java/com/imsweb/mph/mpgroups/Mp1998HematopoieticGroup.java

+10-7
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
import java.io.IOException;
77
import java.io.InputStream;
88
import java.io.InputStreamReader;
9+
import java.io.Reader;
910
import java.nio.charset.StandardCharsets;
1011
import java.util.ArrayList;
1112
import java.util.List;
1213

13-
import com.opencsv.CSVReaderBuilder;
14-
import com.opencsv.exceptions.CsvException;
14+
import de.siegmar.fastcsv.reader.CsvReader;
15+
import de.siegmar.fastcsv.reader.NamedCsvRecord;
1516

1617
import com.imsweb.mph.MphConstants;
1718
import com.imsweb.mph.MphGroup;
@@ -23,7 +24,7 @@
2324

2425
public class Mp1998HematopoieticGroup extends MphGroup {
2526

26-
private static List<String[]> _HEMATOPOIETIC_1998 = new ArrayList<>();
27+
private static final List<String[]> _HEMATOPOIETIC_1998 = new ArrayList<>();
2728

2829
public Mp1998HematopoieticGroup() {
2930
super(MphConstants.HEMATO_2000_AND_EARLIER, MphConstants.HEMATOPOIETIC_AND_LYMPHOID_2000_AND_EARLIER, "C000-C809", null, "9590-9993", null, "2-3,6", "0000-2000");
@@ -49,8 +50,8 @@ public TempRuleResult apply(MphInput i1, MphInput i2, RuleExecutionContext conte
4950
String secondDx = MphConstants.COMPARE_DX_FIRST_LATEST == laterDx ? i1.getHistology() : i2.getHistology();
5051
for (String[] row : _HEMATOPOIETIC_1998)
5152
if ((firstDx.compareTo(row[0]) >= 0 && firstDx.compareTo(row[1]) <= 0 && secondDx.compareTo(row[2]) >= 0 && secondDx.compareTo(row[3]) <= 0) ||
52-
(MphConstants.COMPARE_DX_EQUAL == laterDx && (secondDx.compareTo(row[0]) >= 0 && secondDx.compareTo(row[1]) <= 0 && firstDx.compareTo(row[2]) >= 0 && firstDx.compareTo(
53-
row[3]) <= 0))) {
53+
(MphConstants.COMPARE_DX_EQUAL == laterDx && (secondDx.compareTo(row[0]) >= 0 && secondDx.compareTo(row[1]) <= 0 && firstDx.compareTo(row[2]) >= 0 && firstDx.compareTo(
54+
row[3]) <= 0))) {
5455
result.setFinalResult(MphUtils.MpResult.SINGLE_PRIMARY);
5556
result.setMessage("Single primary based on SEER 1998 multiple primary rules for hematopoietic cancer.");
5657
return result;
@@ -70,9 +71,11 @@ private static synchronized void initializeLookup() {
7071
try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("Hematopoietic1998HistologyPairs.csv")) {
7172
if (is == null)
7273
throw new IllegalStateException("Unable to read Hematopoietic1998HistologyPairs.csv");
73-
_HEMATOPOIETIC_1998.addAll(new CSVReaderBuilder(new InputStreamReader(is, StandardCharsets.US_ASCII)).withSkipLines(1).build().readAll());
74+
try (Reader reader = new InputStreamReader(is, StandardCharsets.US_ASCII); CsvReader<NamedCsvRecord> csvReader = CsvReader.builder().ofNamedCsvRecord(reader)) {
75+
csvReader.stream().forEach(line -> _HEMATOPOIETIC_1998.add(line.getFields().toArray(new String[0])));
76+
}
7477
}
75-
catch (CsvException | IOException e) {
78+
catch (IOException e) {
7679
throw new IllegalStateException(e);
7780
}
7881
}

‎src/main/java/com/imsweb/mph/mpgroups/Mp2001HematopoieticGroup.java

+13-8
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
import java.io.IOException;
77
import java.io.InputStream;
88
import java.io.InputStreamReader;
9+
import java.io.Reader;
910
import java.nio.charset.StandardCharsets;
1011
import java.util.ArrayList;
1112
import java.util.List;
1213

13-
import com.opencsv.CSVReaderBuilder;
14-
import com.opencsv.exceptions.CsvException;
14+
import de.siegmar.fastcsv.reader.CsvReader;
15+
import de.siegmar.fastcsv.reader.NamedCsvRecord;
1516

1617
import com.imsweb.mph.MphConstants;
1718
import com.imsweb.mph.MphGroup;
@@ -23,8 +24,8 @@
2324

2425
public class Mp2001HematopoieticGroup extends MphGroup {
2526

26-
private static List<String[]> _2001_HEMATOPOIETIC_GROUPS = new ArrayList<>();
27-
private static List<String[]> _2001_HEMATOPOIETIC_GROUP_PAIRS = new ArrayList<>();
27+
private static final List<String[]> _2001_HEMATOPOIETIC_GROUPS = new ArrayList<>();
28+
private static final List<String[]> _2001_HEMATOPOIETIC_GROUP_PAIRS = new ArrayList<>();
2829

2930
public Mp2001HematopoieticGroup() {
3031
super(MphConstants.HEMATO_2001_TO_2009, MphConstants.HEMATOPOIETIC_AND_LYMPHOID_2001_2009, "C000-C809", null, "9590-9993", null, "2-3,6", "2001-2009");
@@ -82,17 +83,21 @@ private static synchronized void initializeLookups() {
8283
try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("Hematopoietic2001HistologyGroups.csv")) {
8384
if (is == null)
8485
throw new IllegalStateException("Unable to read Hematopoietic2001HistologyGroups.csv");
85-
_2001_HEMATOPOIETIC_GROUPS.addAll(new CSVReaderBuilder(new InputStreamReader(is, StandardCharsets.US_ASCII)).withSkipLines(1).build().readAll());
86+
try (Reader reader = new InputStreamReader(is, StandardCharsets.US_ASCII); CsvReader<NamedCsvRecord> csvReader = CsvReader.builder().ofNamedCsvRecord(reader)) {
87+
csvReader.stream().forEach(line -> _2001_HEMATOPOIETIC_GROUPS.add(line.getFields().toArray(new String[0])));
88+
}
8689
}
87-
catch (CsvException | IOException e) {
90+
catch (IOException e) {
8891
throw new IllegalStateException(e);
8992
}
9093
try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("Hematopoietic2001HistologyGroupPairs.csv")) {
9194
if (is == null)
9295
throw new IllegalStateException("Unable to read Hematopoietic2001HistologyGroupPairs.csv");
93-
_2001_HEMATOPOIETIC_GROUP_PAIRS.addAll(new CSVReaderBuilder(new InputStreamReader(is, StandardCharsets.US_ASCII)).withSkipLines(1).build().readAll());
96+
try (Reader reader = new InputStreamReader(is, StandardCharsets.US_ASCII); CsvReader<NamedCsvRecord> csvReader = CsvReader.builder().ofNamedCsvRecord(reader)) {
97+
csvReader.stream().forEach(line -> _2001_HEMATOPOIETIC_GROUP_PAIRS.add(line.getFields().toArray(new String[0])));
98+
}
9499
}
95-
catch (CsvException | IOException e) {
100+
catch (IOException e) {
96101
throw new IllegalStateException(e);
97102
}
98103
}

‎src/main/resources/Hematopoietic2010SamePrimaryPairs.csv

+3,057-3,057
Large diffs are not rendered by default.

‎src/main/resources/Hematopoietic2010TransformFromPairs.csv

+483-483
Large diffs are not rendered by default.

‎src/main/resources/Hematopoietic2010TransformToPairs.csv

+392-392
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
#Thu Jan 16 10:24:18 EST 2025
2-
last_updated=202501161024
1+
#Tue Jan 28 12:58:57 EST 2025
2+
last_updated=202501281258

‎src/test/java/lab/HematoDataLab.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import java.util.Map;
1717
import java.util.Properties;
1818

19-
import com.opencsv.CSVWriter;
19+
import de.siegmar.fastcsv.writer.CsvWriter;
2020

2121
import com.imsweb.seerapi.client.NotFoundException;
2222
import com.imsweb.seerapi.client.SeerApi;
@@ -42,9 +42,9 @@ public static void main(String[] args) throws Exception {
4242
File transformFromFile = new File(dir, "Hematopoietic2010TransformFromPairs.csv");
4343

4444
try (OutputStream hematoDataInfoOutput = Files.newOutputStream(hematoDataInfoFile.toPath());
45-
CSVWriter samePrimaryWriter = new CSVWriter(new OutputStreamWriter(Files.newOutputStream(samePrimaryFile.toPath()), StandardCharsets.UTF_8));
46-
CSVWriter transformToWriter = new CSVWriter(new OutputStreamWriter(Files.newOutputStream(transformToFile.toPath()), StandardCharsets.UTF_8));
47-
CSVWriter transformFromWriter = new CSVWriter(new OutputStreamWriter(Files.newOutputStream(transformFromFile.toPath()), StandardCharsets.UTF_8))) {
45+
CsvWriter samePrimaryWriter = CsvWriter.builder().build(new OutputStreamWriter(Files.newOutputStream(samePrimaryFile.toPath()), StandardCharsets.UTF_8));
46+
CsvWriter transformToWriter = CsvWriter.builder().build(new OutputStreamWriter(Files.newOutputStream(transformToFile.toPath()), StandardCharsets.UTF_8));
47+
CsvWriter transformFromWriter = CsvWriter.builder().build(new OutputStreamWriter(Files.newOutputStream(transformFromFile.toPath()), StandardCharsets.UTF_8))) {
4848

4949
SeerApi api = new SeerApi.Builder().connect();
5050
List<Disease> allDiseases = new ArrayList<>();
@@ -137,9 +137,9 @@ else if (previousTotal != total) {
137137
transformFrom.add(new String[] {morphology, validStartYear, validEndYear, startYear, endYear, transformFromMorphology.getIcdO3Morphology()});
138138
}
139139
}
140-
samePrimaryWriter.writeAll(samePrimaryPairs);
141-
transformToWriter.writeAll(transformTo);
142-
transformFromWriter.writeAll(transformFrom);
140+
samePrimaryPairs.forEach(samePrimaryWriter::writeRecord);
141+
transformTo.forEach(transformToWriter::writeRecord);
142+
transformFrom.forEach(transformFromWriter::writeRecord);
143143
Properties prop = new Properties();
144144
prop.setProperty("last_updated", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddkkmm")));
145145
prop.store(hematoDataInfoOutput, null);

0 commit comments

Comments
 (0)
Please sign in to comment.