Skip to content

Commit

Permalink
1.5.0 add custom Map implementations for @ExcelUnknownCells support
Browse files Browse the repository at this point in the history
  • Loading branch information
vaa25 committed Mar 17, 2024
1 parent 96afaf7 commit bc27082
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 58 deletions.
1 change: 1 addition & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,4 @@ Also:
- Poiji2 can read lists in row (use `@ExcelList` on `List`)
- Poiji2 can read and write huge xlsx files (see HugeTest.java)
- Poiji2 (since v1.4.0) can work with immutable java classes (see IgnoreTest.java). lombok @Value and java records applicable also.
- Poiji2 (since v1.5.0) can read sheet names (see ReadSheetNamesTest.java).
21 changes: 5 additions & 16 deletions src/main/java/com/poiji/bind/mapping/ReadMappedFields.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,15 @@
package com.poiji.bind.mapping;

import com.poiji.annotation.ExcelCell;
import com.poiji.annotation.ExcelCellName;
import com.poiji.annotation.ExcelCellRange;
import com.poiji.annotation.ExcelList;
import com.poiji.annotation.ExcelParseExceptions;
import com.poiji.annotation.ExcelRow;
import com.poiji.annotation.ExcelUnknownCells;
import com.poiji.annotation.ExcelWriteOnly;
import com.poiji.annotation.*;
import com.poiji.config.Casting;
import com.poiji.exception.ExcelParseException;
import com.poiji.option.PoijiOptions;
import com.poiji.util.AnnotationUtil;
import com.poiji.util.ReflectUtil;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;

import static com.poiji.annotation.ExcelCellName.ABSENT_ORDER;
import static java.util.Arrays.asList;
Expand Down Expand Up @@ -127,7 +116,7 @@ public void setCellInData(final int row, final int column, final String content,
for (final Field unknownField : unknownFields) {
final Object unknownData = data.get(unknownField);
if (unknownData == null) {
final Map<String, String> map = new HashMap<>();
final Map<String, String> map = ReflectUtil.newMap(unknownField);
data.put(unknownField, map);
map.put(unknownColumns.get(column), content);
} else {
Expand Down Expand Up @@ -241,7 +230,7 @@ private List<String> getPossibleFieldNames(final ExcelCellName annotation) {
private List<Field> parseUnknownCells(final List<Field> fields) {
final List<Field> rest = new ArrayList<>(fields.size());
for (final Field field : fields) {
if (field.getAnnotation(ExcelUnknownCells.class) != null && field.getType().isAssignableFrom(Map.class)) {
if (field.isAnnotationPresent(ExcelUnknownCells.class) && Map.class.isAssignableFrom(field.getType())) {
unknownFields.add(field);
if (!field.isAccessible()) {
field.setAccessible(true);
Expand Down
13 changes: 9 additions & 4 deletions src/main/java/com/poiji/util/ReflectUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.*;

public class ReflectUtil {
public static <T> T newInstanceOf(Class<T> type) {
Expand Down Expand Up @@ -182,4 +179,12 @@ public static <T> T getFieldData(String fieldName, Object instance) {
throw new PoijiException(e.getMessage(), e);
}
}

public static <K, V> Map<K, V> newMap(Field field) {
final Class<?> type = field.getType();
if (type == Map.class) {
return new LinkedHashMap<>();
}
return (Map<K, V>) newInstanceOf(type);
}
}
13 changes: 7 additions & 6 deletions src/test/java/com/poiji/deserialize/CaseInsensitiveTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import com.poiji.bind.Poiji;
import com.poiji.deserialize.model.byname.OrgWithUnknownCellsByName;
import com.poiji.option.PoijiOptions;
import java.io.File;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.io.File;
import java.util.List;

import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
Expand Down Expand Up @@ -46,16 +47,16 @@ public void caseInsensitiveColumnNames() {
.filter(org -> org.getId().equals("CrEaTe"))
.findFirst()
.get();
assertThat(firstRow.getUnknownCells().size(), is(1));
assertThat(firstRow.getUnknownCells().get("region"), is("EMEA"));
assertThat(firstRow.getSortedUnknownCells().size(), is(1));
assertThat(firstRow.getSortedUnknownCells().get("region"), is("EMEA"));


OrgWithUnknownCellsByName secondRow = organisations.stream()
.filter(org -> org.getId().equals("8d9e6430-8626-4556-8004-079085d2df2d"))
.findFirst()
.get();
assertThat(secondRow.getUnknownCells().size(), is(1));
assertThat(secondRow.getUnknownCells().get("region"), is("NA"));
assertThat(secondRow.getSortedUnknownCells().size(), is(1));
assertThat(secondRow.getSortedUnknownCells().get("region"), is("NA"));
}

}
13 changes: 7 additions & 6 deletions src/test/java/com/poiji/deserialize/IgnoreWhitespacesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import com.poiji.bind.Poiji;
import com.poiji.deserialize.model.byname.OrgWithUnknownCellsByName;
import com.poiji.option.PoijiOptions;
import java.io.File;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.io.File;
import java.util.List;

import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
Expand Down Expand Up @@ -51,16 +52,16 @@ public void ignoreWhitespaceColumnNames() {
.filter(org -> org.getId().equals("CrEaTe"))
.findFirst()
.get();
assertThat(firstRow.getUnknownCells().size(), is(1));
assertThat(firstRow.getUnknownCells().get("region"), is("EMEA"));
assertThat(firstRow.getSortedUnknownCells().size(), is(1));
assertThat(firstRow.getSortedUnknownCells().get("region"), is("EMEA"));


OrgWithUnknownCellsByName secondRow = organisations.stream()
.filter(org -> org.getId().equals("8d9e6430-8626-4556-8004-079085d2df2d"))
.findFirst()
.get();
assertThat(secondRow.getUnknownCells().size(), is(1));
assertThat(secondRow.getUnknownCells().get("region"), is("NA"));
assertThat(secondRow.getSortedUnknownCells().size(), is(1));
assertThat(secondRow.getSortedUnknownCells().get("region"), is("NA"));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
import com.poiji.deserialize.model.byid.OrgWithUnknownCells;
import com.poiji.deserialize.model.byname.OrgWithUnknownCellsByName;
import com.poiji.option.PoijiOptions;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.io.File;
import java.util.Arrays;
import java.util.List;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
Expand Down Expand Up @@ -50,18 +51,18 @@ public void byName() {
.filter(org -> org.getId().equals("CrEaTe"))
.findFirst()
.get();
assertThat(firstRow.getUnknownCells().size(), is(2));
assertThat(firstRow.getUnknownCells().get("Tag"), is("testTag"));
assertThat(firstRow.getUnknownCells().get("Tag@5"), is("rndTag"));
assertThat(firstRow.getSortedUnknownCells().size(), is(2));
assertThat(firstRow.getSortedUnknownCells().get("Tag"), is("testTag"));
assertThat(firstRow.getSortedUnknownCells().get("Tag@5"), is("rndTag"));


OrgWithUnknownCellsByName secondRow = organisations.stream()
.filter(org -> org.getId().equals("8d9e6430-8626-4556-8004-079085d2df2d"))
.findFirst()
.get();
assertThat(secondRow.getUnknownCells().size(), is(2));
assertThat(secondRow.getUnknownCells().get("Tag"), is("testTag2"));
assertThat(secondRow.getUnknownCells().get("Tag@5"), is("rndTag2"));
assertThat(secondRow.getSortedUnknownCells().size(), is(2));
assertThat(secondRow.getSortedUnknownCells().get("Tag"), is("testTag2"));
assertThat(secondRow.getSortedUnknownCells().get("Tag@5"), is("rndTag2"));
}

@Test
Expand Down
95 changes: 85 additions & 10 deletions src/test/java/com/poiji/deserialize/UnknownCellsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
import com.poiji.deserialize.model.byid.OrgWithUnknownCells;
import com.poiji.deserialize.model.byname.OrgWithUnknownCellsByName;
import com.poiji.option.PoijiOptions;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.io.File;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
Expand All @@ -34,7 +37,7 @@ public static List<String> excel() {
}

@Test
public void byName() {
public void byNameFromTreeMap() {
List<OrgWithUnknownCellsByName> organisations = Poiji.fromExcel(
new File(path),
OrgWithUnknownCellsByName.class,
Expand All @@ -50,16 +53,88 @@ public void byName() {
.filter(org -> org.getId().equals("CrEaTe"))
.findFirst()
.get();
assertThat(firstRow.getUnknownCells().size(), is(1));
assertThat(firstRow.getUnknownCells().get("Region"), is("EMEA"));
final Map<String, String> unknownCells1 = firstRow.getSortedUnknownCells();
assertThat(unknownCells1.size(), is(4));

assertRow1Values(unknownCells1);

final Iterator<String> iterator1 = unknownCells1.keySet().iterator();
assertThat(iterator1.next(), is("Region"));
assertThat(iterator1.next(), is("UnknownName1"));
assertThat(iterator1.next(), is("UnknownName2"));
assertThat(iterator1.next(), is("UnknownName3"));

OrgWithUnknownCellsByName secondRow = organisations.stream()
.filter(org -> org.getId().equals("8d9e6430-8626-4556-8004-079085d2df2d"))
.findFirst()
.get();
assertThat(secondRow.getUnknownCells().size(), is(1));
assertThat(secondRow.getUnknownCells().get("Region"), is("NA"));
final Map<String, String> unknownCells2 = secondRow.getSortedUnknownCells();
assertRow2Values(unknownCells2);

final Iterator<String> iterator2 = unknownCells2.keySet().iterator();
assertThat(iterator2.next(), is("Region"));
assertThat(iterator2.next(), is("UnknownName1"));
assertThat(iterator2.next(), is("UnknownName2"));
assertThat(iterator2.next(), is("UnknownName3"));

}

@Test
public void byNameFromMap() {
List<OrgWithUnknownCellsByName> organisations = Poiji.fromExcel(
new File(path),
OrgWithUnknownCellsByName.class,
PoijiOptions.PoijiOptionsBuilder.settings()
.sheetName("Organisation")
.build()
);

assertThat(organisations, notNullValue());
assertThat(organisations.size(), is(2));

OrgWithUnknownCellsByName firstRow = organisations.stream()
.filter(org -> org.getId().equals("CrEaTe"))
.findFirst()
.get();
final Map<String, String> unknownCells1 = firstRow.getLinkedUnknownCells();
assertThat(unknownCells1.size(), is(4));

assertRow1Values(unknownCells1);

final Iterator<String> iterator1 = unknownCells1.keySet().iterator();
assertThat(iterator1.next(), is("Region"));
assertThat(iterator1.next(), is("UnknownName3"));
assertThat(iterator1.next(), is("UnknownName1"));
assertThat(iterator1.next(), is("UnknownName2"));

OrgWithUnknownCellsByName secondRow = organisations.stream()
.filter(org -> org.getId().equals("8d9e6430-8626-4556-8004-079085d2df2d"))
.findFirst()
.get();
final Map<String, String> unknownCells2 = secondRow.getLinkedUnknownCells();
assertRow2Values(unknownCells2);

final Iterator<String> iterator2 = unknownCells2.keySet().iterator();
assertThat(iterator2.next(), is("Region"));
assertThat(iterator2.next(), is("UnknownName3"));
assertThat(iterator2.next(), is("UnknownName1"));
assertThat(iterator2.next(), is("UnknownName2"));

}

private void assertRow1Values(Map<String, String> unknownCells1) {
assertThat(unknownCells1.get("Region"), is("EMEA"));
assertThat(unknownCells1.get("UnknownName1"), is("UnknownValue11"));
assertThat(unknownCells1.get("UnknownName2"), is("UnknownValue21"));
assertThat(unknownCells1.get("UnknownName3"), is("UnknownValue31"));
}

private void assertRow2Values(Map<String, String> unknownCells2) {
assertThat(unknownCells2.size(), is(4));
assertThat(unknownCells2.get("Region"), is("NA"));
assertThat(unknownCells2.get("UnknownName1"), is("UnknownValue12"));
assertThat(unknownCells2.get("UnknownName2"), is("UnknownValue22"));
assertThat(unknownCells2.get("UnknownName3"), is("UnknownValue32"));
}

@Test
Expand All @@ -79,15 +154,15 @@ public void byIndex() {
.filter(org -> org.getId().equals("CrEaTe"))
.findFirst()
.get();
assertThat(firstRow.getUnknownCells().size(), is(1));
assertThat(firstRow.getUnknownCells().size(), is(4));
assertThat(firstRow.getUnknownCells().get("Region"), is("EMEA"));


OrgWithUnknownCells secondRow = organisations.stream()
.filter(org -> org.getId().equals("8d9e6430-8626-4556-8004-079085d2df2d"))
.findFirst()
.get();
assertThat(secondRow.getUnknownCells().size(), is(1));
assertThat(secondRow.getUnknownCells().size(), is(4));
assertThat(secondRow.getUnknownCells().get("Region"), is("NA"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.poiji.annotation.ExcelUnknownCells;

import java.util.Map;
import java.util.TreeMap;

public class OrgWithUnknownCellsByName {

Expand All @@ -23,10 +24,13 @@ public class OrgWithUnknownCellsByName {
private String externalId;

@ExcelUnknownCells
private Map<String, String> unknownCells;
private TreeMap<String, String> sortedUnknownCells;

public Map<String, String> getUnknownCells() {
return unknownCells;
@ExcelUnknownCells
private Map<String, String> linkedUnknownCells;

public Map<String, String> getSortedUnknownCells() {
return sortedUnknownCells;
}

@ExcelCellName(HEADER_ORGANISATION_NAME)
Expand Down Expand Up @@ -74,4 +78,8 @@ public String getCustomerExternalId() {
public void setCustomerExternalId(String customerExternalId) {
this.customerExternalId = customerExternalId;
}

public Map<String, String> getLinkedUnknownCells() {
return linkedUnknownCells;
}
}
8 changes: 4 additions & 4 deletions src/test/resources/unknown-cells.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"Organisation ID","Customer External ID","Organisation External ID","Organisation Name","Region"
,,,,
"CrEaTe","customerOrgExt","createOrgExt","createOrg","EMEA"
"8d9e6430-8626-4556-8004-079085d2df2d","customerOrgExt","updateOrgExt","updateOrg","NA"
Organisation ID,Customer External ID,Organisation External ID,Organisation Name,Region,UnknownName3,UnknownName1,UnknownName2
,,,,,,,
CrEaTe,customerOrgExt,createOrgExt,createOrg,EMEA,UnknownValue31,UnknownValue11,UnknownValue21
8d9e6430-8626-4556-8004-079085d2df2d,customerOrgExt,updateOrgExt,updateOrg,NA,UnknownValue32,UnknownValue12,UnknownValue22
Binary file modified src/test/resources/unknown-cells.xls
Binary file not shown.
Binary file modified src/test/resources/unknown-cells.xlsx
Binary file not shown.

0 comments on commit bc27082

Please sign in to comment.