Skip to content

Commit 9d5af92

Browse files
authored
Merge pull request #273 from ozlerhakan/4.1.0
v4.1.0
2 parents 241d99d + 1621c2c commit 9d5af92

File tree

5 files changed

+104
-44
lines changed

5 files changed

+104
-44
lines changed

README.adoc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
:toclevels: 2
33

44
= Poiji
5-
:version: v4.0.0
6-
:branch: 4.0.0
5+
:version: v4.1.0
6+
:branch: 4.1.0
77

88
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"]
99
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"]
@@ -25,7 +25,7 @@ In your Maven/Gradle project, first add the corresponding dependency:
2525
<dependency>
2626
<groupId>com.github.ozlerhakan</groupId>
2727
<artifactId>poiji</artifactId>
28-
<version>4.0.0</version>
28+
<version>4.1.0</version>
2929
</dependency>
3030
----
3131

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
<groupId>com.github.ozlerhakan</groupId>
77
<artifactId>poiji</artifactId>
8-
<version>4.0.0</version>
8+
<version>4.1.0</version>
99
<packaging>jar</packaging>
1010

1111
<name>poiji</name>

src/main/java/com/poiji/bind/mapping/HSSFUnmarshaller.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,9 @@ private <T> T tailSetFieldValue(Row currentRow, Class<? super T> type, T instanc
197197
} else {
198198
mapColumns(currentRow, instance, mappedColumnIndices, errors, field);
199199
}
200-
if (!errors.isEmpty()) {
201-
throw new PoijiMultiRowException("Problem(s) occurred while reading data", errors);
202-
}
200+
}
201+
if (!errors.isEmpty()) {
202+
throw new PoijiMultiRowException("Problem(s) occurred while reading data", errors);
203203
}
204204

205205
Map<String, String> excelUnknownCellsMap = StreamSupport

src/main/java/com/poiji/config/DefaultCasting.java

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.time.LocalDateTime;
1616
import java.time.format.DateTimeParseException;
1717
import java.util.*;
18+
import java.util.function.Predicate;
1819
import java.util.stream.Collectors;
1920
import java.util.stream.Stream;
2021

@@ -133,16 +134,20 @@ private BigDecimal bigDecimalValue(String value, String sheetName, int row, int
133134
}
134135
}
135136

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

138-
//ISSUE #57
139-
//if a date regex has been specified then it wont be null
140-
//so then make sure the string matches the pattern
141-
//if it doesn't, fall back to default
142-
//else continue to turn string into java date
143-
144-
//the reason for this is sometime Java will manage to parse a string to a date object
145-
//without any exceptions but since the string was not an exact match you get a very strange date
146151
if (options.getDateRegex() != null && !value.matches(options.getDateRegex())) {
147152
return options.preferNullOverDefault() ? null : Calendar.getInstance().getTime();
148153
} else {
@@ -151,21 +156,25 @@ private Date dateValue(String value, String sheetName, int row, int col, PoijiOp
151156
sdf.setLenient(options.getDateLenient());
152157
return sdf.parse(value);
153158
} catch (ParseException e) {
154-
return onError(value, sheetName, row, col, e, options.preferNullOverDefault() ? null : Calendar.getInstance().getTime());
159+
return onError(value, sheetName, row, col, e,
160+
options.preferNullOverDefault() ? null : Calendar.getInstance().getTime());
155161
}
156162
}
157163
}
158164

165+
/*
166+
* ISSUE #57
167+
* if a date regex has been specified then it wont be null
168+
* so then make sure the string matches the pattern
169+
* if it doesn't, fall back to default
170+
* else continue to turn string into java date
171+
*
172+
* the reason for this is sometime java will manage to parse a string to a
173+
* date object without any exceptions but since the string was not an exact
174+
* match you get a very strange date
175+
*
176+
*/
159177
private LocalDate localDateValue(String value, String sheetName, int row, int col, PoijiOptions options) {
160-
161-
//ISSUE #57
162-
//if a date regex has been specified then it wont be null
163-
//so then make sure the string matches the pattern
164-
//if it doesn't, fall back to default
165-
//else continue to turn string into java date
166-
167-
//the reason for this is sometime java will manage to parse a string to a date object
168-
//without any exceptions but since the string was not an exact match you get a very strange date
169178
if (options.getDateRegex() != null && !value.matches(options.getDateRegex())) {
170179
return options.preferNullOverDefault() ? null : LocalDate.now();
171180
} else {
@@ -184,18 +193,19 @@ private LocalDateTime localDateTimeValue(String value, String sheetName, int row
184193
try {
185194
return LocalDateTime.parse(value, options.dateTimeFormatter());
186195
} catch (DateTimeParseException e) {
187-
return onError(value, sheetName, row, col, e, options.preferNullOverDefault() ? null : LocalDateTime.now());
196+
return onError(value, sheetName, row, col, e,
197+
options.preferNullOverDefault() ? null : LocalDateTime.now());
188198
}
189199
}
190200
}
191201

192-
193202
private Object enumValue(String value, String sheetName, int row, int col, Class<?> type) {
194203
return Arrays.stream(type.getEnumConstants())
195204
.filter(o -> ((Enum<?>) o).name().equals(value))
196205
.findFirst()
197206
.orElseGet(() -> {
198-
IllegalArgumentException e = new IllegalArgumentException("No enumeration " + type.getSimpleName() + "." + value);
207+
IllegalArgumentException e = new IllegalArgumentException(
208+
"No enumeration " + type.getSimpleName() + "." + value);
199209
return onError(value, sheetName, row, col, e, null);
200210
});
201211
}
@@ -204,33 +214,34 @@ private Object castListValue(String value, String sheetName, int row, int col, F
204214
final ParameterizedType genericType = (ParameterizedType) field.getGenericType();
205215
final Type fieldType = genericType.getActualTypeArguments()[0];
206216
String[] valueList = value.split(options.getListDelimiter());
217+
Stream<String> valueStream = Stream.of(valueList).filter(Predicate.not(String::isEmpty));
207218

208219
if (fieldType == Integer.class) {
209-
return Stream.of(valueList)
220+
return valueStream
210221
.map(rv -> primitiveIntegerValue(rv, sheetName, row, col))
211222
.collect(Collectors.toList());
212223
} else if (fieldType == BigDecimal.class) {
213-
return Stream.of(valueList)
224+
return valueStream
214225
.map(rv -> bigDecimalValue(rv, sheetName, row, col, options))
215226
.collect(Collectors.toList());
216227
} else if (fieldType == Long.class) {
217-
return Stream.of(valueList)
228+
return valueStream
218229
.map(rv -> longValue(rv, sheetName, row, col, options))
219230
.collect(Collectors.toList());
220231
} else if (fieldType == Double.class) {
221-
return Stream.of(valueList)
232+
return valueStream
222233
.map(rv -> doubleValue(rv, sheetName, row, col, options))
223234
.collect(Collectors.toList());
224235
} else if (fieldType == Boolean.class) {
225-
return Stream.of(valueList)
236+
return valueStream
226237
.map(rv -> booleanValue(rv, sheetName, row, col, options))
227238
.collect(Collectors.toList());
228239
} else if (fieldType == Float.class) {
229-
return Stream.of(valueList)
240+
return valueStream
230241
.map(rv -> floatValue(rv, sheetName, row, col, options))
231242
.collect(Collectors.toList());
232243
} else {
233-
return Arrays.asList(valueList);
244+
return valueStream.collect(Collectors.toList());
234245
}
235246
}
236247

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

243-
protected Object getValueObject(Field field, int row, int col, PoijiOptions options, String rawValue, Class<?> fieldType) {
254+
protected Object getValueObject(Field field, int row, int col, PoijiOptions options, String rawValue,
255+
Class<?> fieldType) {
244256
String sheetName = options.getSheetName();
245257
String value = options.trimCellValue() ? rawValue.trim() : rawValue;
246258

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

290302
} else if (fieldType.isEnum()) {
291303
o = enumValue(value, sheetName, row, col, fieldType);
292-
293-
} else if (value.isEmpty()) {
294-
o = options.preferNullOverDefault() ? null : value;
295304
} else if (fieldType == List.class) {
296305
o = castListValue(value, sheetName, row, col, field, options);
306+
} else if (value.isEmpty()) {
307+
o = options.preferNullOverDefault() ? null : value;
297308
} else {
298309
o = value;
299310

src/test/java/com/poiji/util/DefaultCastingTest.java

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,19 @@ public void castLocalDateUnmatchedDateRegex() {
6262
assertNull(testLocalDate);
6363
}
6464

65+
@Test
66+
public void castLocalDateUnmatchedDateRegexPreferNotNull() {
67+
68+
PoijiOptions options = PoijiOptionsBuilder.settings()
69+
.dateRegex("\\d{2}\\/\\d{2}\\/\\d{4}")
70+
.preferNullOverDefault(false)
71+
.build();
72+
73+
LocalDate testLocalDate = (LocalDate) casting.castValue(LocalDate.class, "05-01-2016", options);
74+
75+
assertNotNull(testLocalDate);
76+
}
77+
6578
@Test
6679
public void castDate() throws Exception {
6780

@@ -187,11 +200,48 @@ public void castLocalDateTime() {
187200

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

190-
LocalDateTime actualDate = (LocalDateTime) casting.castValue(LocalDateTime.class, "01/08/2018 10:00:00", options);
203+
LocalDateTime actualDate = (LocalDateTime) casting.castValue(LocalDateTime.class, "01/08/2018 10:00:00",
204+
options);
191205

192206
assertEquals(expectedDate, actualDate);
193207
}
194208

209+
@Test
210+
public void invalidValueLocalDateTime() {
211+
PoijiOptions options = PoijiOptionsBuilder.settings().build();
212+
213+
LocalDateTime expectedDate = LocalDateTime.now();
214+
215+
LocalDateTime actualDate = (LocalDateTime) casting.castValue(LocalDateTime.class, "", options);
216+
217+
assertEquals(expectedDate.toLocalDate(), actualDate.toLocalDate());
218+
}
219+
220+
@Test
221+
public void invalidValueLocalDateTimeWhenRegexNotMatch() {
222+
PoijiOptions options = PoijiOptionsBuilder.settings().dateTimeRegex("d{2}/d{2}/d{4} d{2}:d{2}:d{2}")
223+
.build();
224+
225+
LocalDateTime expectedDate = LocalDateTime.now();
226+
227+
LocalDateTime actualDate = (LocalDateTime) casting.castValue(LocalDateTime.class, "01/8/2023 10:00:00",
228+
options);
229+
230+
assertEquals(expectedDate.toLocalDate(), actualDate.toLocalDate());
231+
}
232+
233+
@Test
234+
public void invalidValueLocalDateTimeWhenRegexNotMatchPreferNull() {
235+
PoijiOptions options = PoijiOptionsBuilder.settings().dateTimeRegex("d{2}/d{2}/d{4} d{2}:d{2}:d{2}")
236+
.preferNullOverDefault(true)
237+
.build();
238+
239+
LocalDateTime actualDate = (LocalDateTime) casting.castValue(LocalDateTime.class, "01/8/2023 10:00:00",
240+
options);
241+
242+
assertNull(actualDate);
243+
}
244+
195245
@Test
196246
public void castBigDecimalDE() {
197247
PoijiOptions options = PoijiOptionsBuilder.settings().setLocale(Locale.GERMANY).build();
@@ -200,7 +250,6 @@ public void castBigDecimalDE() {
200250
assertEquals(BigDecimal.valueOf(81.56), testVal);
201251
}
202252

203-
204253
@Test
205254
public void castEnum() {
206255

@@ -228,22 +277,22 @@ private enum TestEnum {
228277
}
229278

230279
@Test
231-
//ISSUE #55 : additional functionality, trim string values
280+
// ISSUE #55 : additional functionality, trim string values
232281
public void trimStringDefault() {
233282
String testVal = (String) casting.castValue(String.class, " value ", options);
234283
assertEquals(" value ", testVal);
235284
}
236285

237286
@Test
238-
//ISSUE #55 : additional functionality, trim string values
287+
// ISSUE #55 : additional functionality, trim string values
239288
public void trimStringTrue() {
240289
PoijiOptions options = PoijiOptionsBuilder.settings().build().setTrimCellValue(true);
241290
String testVal = (String) casting.castValue(String.class, " value ", options);
242291
assertEquals("value", testVal);
243292
}
244293

245294
@Test
246-
//ISSUE #55 : additional functionality, trim string values
295+
// ISSUE #55 : additional functionality, trim string values
247296
public void trimStringFalse() {
248297
PoijiOptions options = PoijiOptionsBuilder.settings().build().setTrimCellValue(false);
249298
String testVal = (String) casting.castValue(String.class, " value ", options);

0 commit comments

Comments
 (0)