Skip to content

Commit

Permalink
Merge pull request #306 from ozlerhakan/4.3.0
Browse files Browse the repository at this point in the history
Release 4.3.0
  • Loading branch information
ozlerhakan committed Feb 25, 2024
2 parents a43533d + 240e27e commit 50fb41a
Show file tree
Hide file tree
Showing 19 changed files with 547 additions and 28 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.2.0
:branch: 4.2.0
:version: v4.3.0
:branch: 4.3.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.3-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.2.0</version>
<version>4.3.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.2.0</version>
<version>4.3.0</version>
<packaging>jar</packaging>

<name>poiji</name>
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/com/poiji/annotation/ExcelCellName.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

/**
* Specifies the column name where the corresponding value is mapped from the
* excel data
* Excel data
*
* @return column name
*/
Expand All @@ -35,4 +35,12 @@
* @return mandatory cell signal. Default is false.
*/
boolean mandatoryCell() default false;

/**
* Specifies the column regular expression where the corresponding value is mapped from the
* Excel data
*
* @return column regular expression
*/
String expression() default "";
}
20 changes: 20 additions & 0 deletions src/main/java/com/poiji/annotation/ExcelCellsJoinedByName.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.poiji.annotation;

import java.lang.annotation.*;

/**
* Created by aerfus on 18/02/2024
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface ExcelCellsJoinedByName {

/**
* Specifies the column regular expression where the corresponding values are mapped from the
* Excel data
*
* @return column regular expression
*/
String expression();
}
105 changes: 94 additions & 11 deletions src/main/java/com/poiji/bind/mapping/HSSFUnmarshaller.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.poiji.annotation.ExcelCellRange;
import com.poiji.annotation.ExcelRow;
import com.poiji.annotation.ExcelUnknownCells;
import com.poiji.annotation.ExcelCellsJoinedByName;
import com.poiji.bind.Unmarshaller;
import com.poiji.config.Casting;
import com.poiji.config.Formatting;
Expand All @@ -15,6 +16,8 @@
import com.poiji.option.PoijiOptions;
import com.poiji.util.AnnotationUtil;
import com.poiji.util.ReflectUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MultiValuedMap;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.BaseFormulaEvaluator;
Expand All @@ -25,6 +28,7 @@
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.NumberToTextConverter;
import org.apache.poi.util.StringUtil;

import java.lang.reflect.Field;
import java.util.ArrayList;
Expand All @@ -35,6 +39,7 @@
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

Expand Down Expand Up @@ -245,34 +250,76 @@ private <T> Integer tailSetFieldValue(Row currentRow, T instance, Field field) {
if (annotationDetail.getColumn() != null) {
constructTypeValue(currentRow, instance, field, annotationDetail);
}

if (CollectionUtils.isNotEmpty(annotationDetail.getColumns())) {
for (Integer column : annotationDetail.getColumns()) {
annotationDetail.setColumn(column);
constructTypeValue(currentRow, instance, field, annotationDetail);
}
}

return annotationDetail.getColumn();
}

private FieldAnnotationDetail getFieldColumn(final Field field) {
ExcelCell index = field.getAnnotation(ExcelCell.class);
DisableCellFormatXLS disableCellFormat = field.getAnnotation(DisableCellFormatXLS.class);
final FieldAnnotationDetail annotationDetail = new FieldAnnotationDetail();

if (disableCellFormat != null) {
annotationDetail.setDisabledCellFormat(disableCellFormat.value());
}

ExcelCell index = field.getAnnotation(ExcelCell.class);
if (index != null) {
annotationDetail.setColumn(index.value());
annotationDetail.setMandatoryCell(index.mandatoryCell());
} else {
ExcelCellName excelCellName = field.getAnnotation(ExcelCellName.class);
if (excelCellName != null) {
annotationDetail.setMandatoryCell(excelCellName.mandatoryCell());
annotationDetail.setColumnName(excelCellName.value());
final String titleName = formatting.transform(options, excelCellName.value());
Integer column = titleToIndex.get(titleName);
annotationDetail.setColumn(column);
}
}

ExcelCellName excelCellName = field.getAnnotation(ExcelCellName.class);
if (excelCellName != null) {
annotationDetail.setMandatoryCell(excelCellName.mandatoryCell());
annotationDetail.setColumnName(excelCellName.value());
Integer column = findTitleColumn(excelCellName);
annotationDetail.setColumn(column);
}

ExcelCellsJoinedByName excelCellsJoinedByName = field.getAnnotation(ExcelCellsJoinedByName.class);
if (excelCellsJoinedByName != null) {
String expression = excelCellsJoinedByName.expression();
Pattern pattern = Pattern.compile(expression);

List<Integer> columns = indexToTitle.entrySet().stream()
.filter(entry -> pattern.matcher(
entry.getValue().replaceAll("@[0-9]+", ""))
.matches())
.map(Map.Entry::getKey)
.collect(Collectors.toList());

annotationDetail.setColumns(columns);
annotationDetail.setMultiValueMap(CollectionUtils.isNotEmpty(columns));
}

return annotationDetail;
}

public Integer findTitleColumn(ExcelCellName excelCellName) {
if (!StringUtil.isBlank(excelCellName.value())) {
final String titleName = formatting.transform(options, excelCellName.value());
return titleToIndex.get(titleName);
}

if (!StringUtil.isBlank(excelCellName.expression())) {
final String titleName = formatting.transform(options, excelCellName.expression());
Pattern pattern = Pattern.compile(titleName);
return titleToIndex.entrySet().stream()
.filter(entry -> pattern.matcher(entry.getKey()).matches())
.findFirst()
.map(Map.Entry::getValue)
.orElse(null);
}
return null;
}

private <T> void constructTypeValue(Row currentRow, T instance, Field field,
FieldAnnotationDetail annotationDetail) {
Cell cell = currentRow.getCell(annotationDetail.getColumn());
Expand All @@ -289,7 +336,14 @@ private <T> void constructTypeValue(Row currentRow, T instance, Field field,
}
Object data = casting.castValue(field, value, currentRow.getRowNum(), annotationDetail.getColumn(),
options);
setFieldData(instance, field, data);

if (!annotationDetail.isMultiValueMap()) {
setFieldData(instance, field, data);
} else {
String titleColumn = indexToTitle.get(annotationDetail.getColumn());
titleColumn = titleColumn.replaceAll("@[0-9]+", "");
putFieldMultiValueMapData(instance, field, titleColumn, data);
}
} else if (annotationDetail.isMandatoryCell()) {
throw new PoijiRowSpecificException(annotationDetail.getColumnName(), field.getName(),
currentRow.getRowNum());
Expand All @@ -311,6 +365,16 @@ private <T> void setFieldData(T instance, Field field, Object data) {
}
}

public void putFieldMultiValueMapData(Object instance, Field field, String columnName, Object o) {
try {
field.setAccessible(true);
MultiValuedMap<String, Object> multiValuedMap = (MultiValuedMap<String, Object>) field.get(instance);
multiValuedMap.put(columnName, o);
} catch (ClassCastException | IllegalAccessException e) {
throw new IllegalCastException("Unexpected cast type {" + o + "} of field" + field.getName());
}
}

private <T> T setFieldValuesFromRowIntoInstance(Row currentRow, Class<? super T> subclass, T instance) {
return subclass == null
? instance
Expand Down Expand Up @@ -338,6 +402,10 @@ private static class FieldAnnotationDetail {
private boolean disabledCellFormat;
private boolean mandatoryCell;

private List<Integer> columns;

private boolean multiValueMap;

Integer getColumn() {
return column;
}
Expand Down Expand Up @@ -370,6 +438,21 @@ public void setMandatoryCell(boolean mandatoryCell) {
this.mandatoryCell = mandatoryCell;
}

public List<Integer> getColumns() {
return columns;
}

public void setColumns(List<Integer> columns) {
this.columns = columns;
}

public boolean isMultiValueMap() {
return multiValueMap;
}

public void setMultiValueMap(boolean multiValueMap) {
this.multiValueMap = multiValueMap;
}
}

}
59 changes: 47 additions & 12 deletions src/main/java/com/poiji/bind/mapping/PoijiHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
import com.poiji.annotation.ExcelCellRange;
import com.poiji.annotation.ExcelRow;
import com.poiji.annotation.ExcelUnknownCells;
import com.poiji.annotation.ExcelCellsJoinedByName;
import com.poiji.config.Casting;
import com.poiji.config.Formatting;
import com.poiji.exception.IllegalCastException;
import com.poiji.option.PoijiOptions;
import com.poiji.util.AnnotationUtil;
import com.poiji.util.ReflectUtil;
import org.apache.poi.ss.util.CellAddress;
import org.apache.poi.util.StringUtil;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler;
import org.apache.poi.xssf.usermodel.XSSFComment;

Expand All @@ -21,6 +23,7 @@
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import static java.lang.String.valueOf;
Expand Down Expand Up @@ -167,23 +170,55 @@ private boolean setValue(Field field, int column, String content, Object ins) {
ReflectUtil.setFieldData(field, o, ins);
return true;
}
} else {
ExcelCellName excelCellName = field.getAnnotation(ExcelCellName.class);
if (excelCellName != null) {
excelCellNameAnnotations.add(excelCellName);
final String titleName = formatting.transform(options, excelCellName.value());
final Integer titleColumn = titleToIndex.get(titleName);
// Fix both columns mapped to name passing this condition below
if (titleColumn != null && titleColumn == column) {
Object o = casting.castValue(field, content, internalRow, column, options);
ReflectUtil.setFieldData(field, o, ins);
return true;
}
}

ExcelCellName excelCellName = field.getAnnotation(ExcelCellName.class);
if (excelCellName != null) {
excelCellNameAnnotations.add(excelCellName);
final Integer titleColumn = findTitleColumn(excelCellName);
// Fix both columns mapped to name passing this condition below
if (titleColumn != null && titleColumn == column) {
Object o = casting.castValue(field, content, internalRow, column, options);
ReflectUtil.setFieldData(field, o, ins);
return true;
}
}

ExcelCellsJoinedByName excelCellsJoinedByName = field.getAnnotation(ExcelCellsJoinedByName.class);
if (excelCellsJoinedByName != null) {
String titleColumn = indexToTitle.get(column).replaceAll("@[0-9]+", "");

String expression = excelCellsJoinedByName.expression();
Pattern pattern = Pattern.compile(expression);
if (pattern.matcher(titleColumn).matches()) {
Object o = casting.castValue(field, content, internalRow, column, options);
ReflectUtil.putFieldMultiValueMapData(field, titleColumn, o, ins);
return true;
}
}

return false;
}

public Integer findTitleColumn(ExcelCellName excelCellName) {
if (!StringUtil.isBlank(excelCellName.value())) {
final String titleName = formatting.transform(options, excelCellName.value());
return titleToIndex.get(titleName);
}

if (!StringUtil.isBlank(excelCellName.expression())) {
final String titleName = formatting.transform(options, excelCellName.expression());
Pattern pattern = Pattern.compile(titleName);
return titleToIndex.entrySet().stream()
.filter(entry -> pattern.matcher(entry.getKey()).matches())
.findFirst()
.map(Map.Entry::getValue)
.orElse(null);
}

return null;
}

@Override
public void startRow(int rowNum) {
if (rowNum + 1 > options.skip()) {
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/com/poiji/util/ReflectUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.poiji.annotation.ExcelCellRange;
import com.poiji.exception.IllegalCastException;
import com.poiji.exception.PoijiInstantiationException;
import org.apache.commons.collections4.MultiValuedMap;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
Expand Down Expand Up @@ -64,4 +65,15 @@ public static void setFieldData(Field field, Object o, Object instance) {
throw new IllegalCastException("Unexpected cast type {" + o + "} of field" + field.getName());
}
}

@SuppressWarnings("unchecked")
public static void putFieldMultiValueMapData(Field field, String columnName, Object o, Object instance) {
try {
field.setAccessible(true);
MultiValuedMap<String, Object> multiValuedMap = (MultiValuedMap<String, Object>) field.get(instance);
multiValuedMap.put(columnName, o);
} catch (IllegalAccessException | IllegalAccessError e) {
throw new IllegalCastException("Unexpected cast type {" + o + "} of field" + field.getName());
}
}
}
Loading

0 comments on commit 50fb41a

Please sign in to comment.