Skip to content

Commit

Permalink
Merge pull request #273 from ozlerhakan/4.1.0
Browse files Browse the repository at this point in the history
v4.1.0
  • Loading branch information
ozlerhakan authored Mar 5, 2023
2 parents 241d99d + 1621c2c commit 9d5af92
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 44 deletions.
6 changes: 3 additions & 3 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
:toclevels: 2

= Poiji
:version: v4.0.0
:branch: 4.0.0
:version: v4.1.0
:branch: 4.1.0

image:https://github.com/ozlerhakan/poiji/actions/workflows/maven.yml/badge.svg["Build Status"] image:https://app.codacy.com/project/badge/Grade/64f7e2cb9e604807b62334a4cfc3952d["Codacy code quality",link="https://www.codacy.com/gh/ozlerhakan/poiji/dashboard?utm_source=github.com&utm_medium=referral&utm_content=ozlerhakan/poiji&utm_campaign=Badge_Grade"]
image:https://codecov.io/gh/ozlerhakan/poiji/branch/{branch}/graph/badge.svg?token=MN6V6xOWBq["Codecov",link="https://codecov.io/gh/ozlerhakan/poiji"] image:https://img.shields.io/badge/apache.poi-5.2.1-brightgreen.svg[] image:https://app.fossa.com/api/projects/git%2Bgithub.com%2Fozlerhakan%2Fpoiji.svg?type=shield["FOSSA Status",link="https://app.fossa.com/projects/git%2Bgithub.com%2Fozlerhakan%2Fpoiji?ref=badge_shield"]
Expand All @@ -25,7 +25,7 @@ In your Maven/Gradle project, first add the corresponding dependency:
<dependency>
<groupId>com.github.ozlerhakan</groupId>
<artifactId>poiji</artifactId>
<version>4.0.0</version>
<version>4.1.0</version>
</dependency>
----

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>com.github.ozlerhakan</groupId>
<artifactId>poiji</artifactId>
<version>4.0.0</version>
<version>4.1.0</version>
<packaging>jar</packaging>

<name>poiji</name>
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/poiji/bind/mapping/HSSFUnmarshaller.java
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,9 @@ private <T> T tailSetFieldValue(Row currentRow, Class<? super T> type, T instanc
} else {
mapColumns(currentRow, instance, mappedColumnIndices, errors, field);
}
if (!errors.isEmpty()) {
throw new PoijiMultiRowException("Problem(s) occurred while reading data", errors);
}
}
if (!errors.isEmpty()) {
throw new PoijiMultiRowException("Problem(s) occurred while reading data", errors);
}

Map<String, String> excelUnknownCellsMap = StreamSupport
Expand Down
75 changes: 43 additions & 32 deletions src/main/java/com/poiji/config/DefaultCasting.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.time.LocalDateTime;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand Down Expand Up @@ -133,16 +134,20 @@ private BigDecimal bigDecimalValue(String value, String sheetName, int row, int
}
}

/*
*
* ISSUE #57
* if a date regex has been specified then it wont be null
* so then make sure the string matches the pattern
* if it doesn't, fall back to default
* else continue to turn string into java date
*
* the reason for this is sometime Java will manage to parse a string to a
* date object without any exceptions but since the string was not an exact
* match you get a very strange date
*/
private Date dateValue(String value, String sheetName, int row, int col, PoijiOptions options) {

//ISSUE #57
//if a date regex has been specified then it wont be null
//so then make sure the string matches the pattern
//if it doesn't, fall back to default
//else continue to turn string into java date

//the reason for this is sometime Java will manage to parse a string to a date object
//without any exceptions but since the string was not an exact match you get a very strange date
if (options.getDateRegex() != null && !value.matches(options.getDateRegex())) {
return options.preferNullOverDefault() ? null : Calendar.getInstance().getTime();
} else {
Expand All @@ -151,21 +156,25 @@ private Date dateValue(String value, String sheetName, int row, int col, PoijiOp
sdf.setLenient(options.getDateLenient());
return sdf.parse(value);
} catch (ParseException e) {
return onError(value, sheetName, row, col, e, options.preferNullOverDefault() ? null : Calendar.getInstance().getTime());
return onError(value, sheetName, row, col, e,
options.preferNullOverDefault() ? null : Calendar.getInstance().getTime());
}
}
}

/*
* ISSUE #57
* if a date regex has been specified then it wont be null
* so then make sure the string matches the pattern
* if it doesn't, fall back to default
* else continue to turn string into java date
*
* the reason for this is sometime java will manage to parse a string to a
* date object without any exceptions but since the string was not an exact
* match you get a very strange date
*
*/
private LocalDate localDateValue(String value, String sheetName, int row, int col, PoijiOptions options) {

//ISSUE #57
//if a date regex has been specified then it wont be null
//so then make sure the string matches the pattern
//if it doesn't, fall back to default
//else continue to turn string into java date

//the reason for this is sometime java will manage to parse a string to a date object
//without any exceptions but since the string was not an exact match you get a very strange date
if (options.getDateRegex() != null && !value.matches(options.getDateRegex())) {
return options.preferNullOverDefault() ? null : LocalDate.now();
} else {
Expand All @@ -184,18 +193,19 @@ private LocalDateTime localDateTimeValue(String value, String sheetName, int row
try {
return LocalDateTime.parse(value, options.dateTimeFormatter());
} catch (DateTimeParseException e) {
return onError(value, sheetName, row, col, e, options.preferNullOverDefault() ? null : LocalDateTime.now());
return onError(value, sheetName, row, col, e,
options.preferNullOverDefault() ? null : LocalDateTime.now());
}
}
}


private Object enumValue(String value, String sheetName, int row, int col, Class<?> type) {
return Arrays.stream(type.getEnumConstants())
.filter(o -> ((Enum<?>) o).name().equals(value))
.findFirst()
.orElseGet(() -> {
IllegalArgumentException e = new IllegalArgumentException("No enumeration " + type.getSimpleName() + "." + value);
IllegalArgumentException e = new IllegalArgumentException(
"No enumeration " + type.getSimpleName() + "." + value);
return onError(value, sheetName, row, col, e, null);
});
}
Expand All @@ -204,33 +214,34 @@ private Object castListValue(String value, String sheetName, int row, int col, F
final ParameterizedType genericType = (ParameterizedType) field.getGenericType();
final Type fieldType = genericType.getActualTypeArguments()[0];
String[] valueList = value.split(options.getListDelimiter());
Stream<String> valueStream = Stream.of(valueList).filter(Predicate.not(String::isEmpty));

if (fieldType == Integer.class) {
return Stream.of(valueList)
return valueStream
.map(rv -> primitiveIntegerValue(rv, sheetName, row, col))
.collect(Collectors.toList());
} else if (fieldType == BigDecimal.class) {
return Stream.of(valueList)
return valueStream
.map(rv -> bigDecimalValue(rv, sheetName, row, col, options))
.collect(Collectors.toList());
} else if (fieldType == Long.class) {
return Stream.of(valueList)
return valueStream
.map(rv -> longValue(rv, sheetName, row, col, options))
.collect(Collectors.toList());
} else if (fieldType == Double.class) {
return Stream.of(valueList)
return valueStream
.map(rv -> doubleValue(rv, sheetName, row, col, options))
.collect(Collectors.toList());
} else if (fieldType == Boolean.class) {
return Stream.of(valueList)
return valueStream
.map(rv -> booleanValue(rv, sheetName, row, col, options))
.collect(Collectors.toList());
} else if (fieldType == Float.class) {
return Stream.of(valueList)
return valueStream
.map(rv -> floatValue(rv, sheetName, row, col, options))
.collect(Collectors.toList());
} else {
return Arrays.asList(valueList);
return valueStream.collect(Collectors.toList());
}
}

Expand All @@ -240,7 +251,8 @@ public Object castValue(Field field, String rawValue, int row, int col, PoijiOpt
return getValueObject(field, row, col, options, rawValue, fieldType);
}

protected Object getValueObject(Field field, int row, int col, PoijiOptions options, String rawValue, Class<?> fieldType) {
protected Object getValueObject(Field field, int row, int col, PoijiOptions options, String rawValue,
Class<?> fieldType) {
String sheetName = options.getSheetName();
String value = options.trimCellValue() ? rawValue.trim() : rawValue;

Expand Down Expand Up @@ -289,11 +301,10 @@ protected Object getValueObject(Field field, int row, int col, PoijiOptions opti

} else if (fieldType.isEnum()) {
o = enumValue(value, sheetName, row, col, fieldType);

} else if (value.isEmpty()) {
o = options.preferNullOverDefault() ? null : value;
} else if (fieldType == List.class) {
o = castListValue(value, sheetName, row, col, field, options);
} else if (value.isEmpty()) {
o = options.preferNullOverDefault() ? null : value;
} else {
o = value;

Expand Down
59 changes: 54 additions & 5 deletions src/test/java/com/poiji/util/DefaultCastingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,19 @@ public void castLocalDateUnmatchedDateRegex() {
assertNull(testLocalDate);
}

@Test
public void castLocalDateUnmatchedDateRegexPreferNotNull() {

PoijiOptions options = PoijiOptionsBuilder.settings()
.dateRegex("\\d{2}\\/\\d{2}\\/\\d{4}")
.preferNullOverDefault(false)
.build();

LocalDate testLocalDate = (LocalDate) casting.castValue(LocalDate.class, "05-01-2016", options);

assertNotNull(testLocalDate);
}

@Test
public void castDate() throws Exception {

Expand Down Expand Up @@ -187,11 +200,48 @@ public void castLocalDateTime() {

LocalDateTime expectedDate = LocalDateTime.of(2018, 8, 1, 10, 00, 00);

LocalDateTime actualDate = (LocalDateTime) casting.castValue(LocalDateTime.class, "01/08/2018 10:00:00", options);
LocalDateTime actualDate = (LocalDateTime) casting.castValue(LocalDateTime.class, "01/08/2018 10:00:00",
options);

assertEquals(expectedDate, actualDate);
}

@Test
public void invalidValueLocalDateTime() {
PoijiOptions options = PoijiOptionsBuilder.settings().build();

LocalDateTime expectedDate = LocalDateTime.now();

LocalDateTime actualDate = (LocalDateTime) casting.castValue(LocalDateTime.class, "", options);

assertEquals(expectedDate.toLocalDate(), actualDate.toLocalDate());
}

@Test
public void invalidValueLocalDateTimeWhenRegexNotMatch() {
PoijiOptions options = PoijiOptionsBuilder.settings().dateTimeRegex("d{2}/d{2}/d{4} d{2}:d{2}:d{2}")
.build();

LocalDateTime expectedDate = LocalDateTime.now();

LocalDateTime actualDate = (LocalDateTime) casting.castValue(LocalDateTime.class, "01/8/2023 10:00:00",
options);

assertEquals(expectedDate.toLocalDate(), actualDate.toLocalDate());
}

@Test
public void invalidValueLocalDateTimeWhenRegexNotMatchPreferNull() {
PoijiOptions options = PoijiOptionsBuilder.settings().dateTimeRegex("d{2}/d{2}/d{4} d{2}:d{2}:d{2}")
.preferNullOverDefault(true)
.build();

LocalDateTime actualDate = (LocalDateTime) casting.castValue(LocalDateTime.class, "01/8/2023 10:00:00",
options);

assertNull(actualDate);
}

@Test
public void castBigDecimalDE() {
PoijiOptions options = PoijiOptionsBuilder.settings().setLocale(Locale.GERMANY).build();
Expand All @@ -200,7 +250,6 @@ public void castBigDecimalDE() {
assertEquals(BigDecimal.valueOf(81.56), testVal);
}


@Test
public void castEnum() {

Expand Down Expand Up @@ -228,22 +277,22 @@ private enum TestEnum {
}

@Test
//ISSUE #55 : additional functionality, trim string values
// ISSUE #55 : additional functionality, trim string values
public void trimStringDefault() {
String testVal = (String) casting.castValue(String.class, " value ", options);
assertEquals(" value ", testVal);
}

@Test
//ISSUE #55 : additional functionality, trim string values
// ISSUE #55 : additional functionality, trim string values
public void trimStringTrue() {
PoijiOptions options = PoijiOptionsBuilder.settings().build().setTrimCellValue(true);
String testVal = (String) casting.castValue(String.class, " value ", options);
assertEquals("value", testVal);
}

@Test
//ISSUE #55 : additional functionality, trim string values
// ISSUE #55 : additional functionality, trim string values
public void trimStringFalse() {
PoijiOptions options = PoijiOptionsBuilder.settings().build().setTrimCellValue(false);
String testVal = (String) casting.castValue(String.class, " value ", options);
Expand Down

0 comments on commit 9d5af92

Please sign in to comment.