Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ private static FieldCache doDeclaredFields(Class<?> clazz, ConfigurationHolder c
FieldWrapper field = entry.getValue();

// The current field needs to be ignored
if (writeHolder.ignore(field.getFieldName(), entry.getKey())) {
if (writeHolder.ignore(field.getField().getName(), entry.getKey())) {
ignoreSet.add(field.getFieldName());
// indexFieldMap is keyed by the field's explicit @ExcelProperty(index), which for
// explicit-index fields equals the sortedFieldMap position (entry.getKey()); remove
Expand Down Expand Up @@ -384,26 +384,31 @@ private static void resortField(WriteHolder writeHolder, FieldCache fieldCache)

Collection<String> includeColumnFieldNames = writeHolder.includeColumnFieldNames();
if (!CollectionUtils.isEmpty(includeColumnFieldNames)) {
// Field sorted map
// Field sorted map, keyed by the Java field name, which is what the user configures
Map<String, Integer> filedIndexMap = MapUtils.newHashMap();
int fieldIndex = 0;
for (String includeColumnFieldName : includeColumnFieldNames) {
filedIndexMap.put(includeColumnFieldName, fieldIndex++);
}
fieldCache
.getSortedFieldMap()
.forEach(
(index, field) -> filedIndexMap.put(field.getField().getName(), index));

// rebuild sortedFieldMap
Map<Integer, FieldWrapper> tempSortedFieldMap = MapUtils.newHashMap();
fieldCache.getSortedFieldMap().forEach((index, field) -> {
Integer tempFieldIndex = filedIndexMap.get(field.getFieldName());
if (tempFieldIndex != null) {
tempSortedFieldMap.put(tempFieldIndex, field);
int fieldIndex = 0;
for (String includeColumnFieldName : includeColumnFieldNames) {
Integer index = filedIndexMap.get(includeColumnFieldName);
// The name is not a field of the class, the column is ignored, it must not hold a position
if (index == null) {
continue;
}
FieldWrapper field = fieldCache.getSortedFieldMap().get(index);
tempSortedFieldMap.put(fieldIndex, field);

// The user has redefined the ordering and the ordering of annotations needs to be invalidated
if (!tempFieldIndex.equals(index)) {
indexFieldMap.remove(index);
}
// The user has redefined the ordering and the ordering of annotations needs to be invalidated
if (fieldIndex != index) {
indexFieldMap.remove(index);
}
});
fieldIndex++;
}
fieldCache.setSortedFieldMap(tempSortedFieldMap);
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/*
* This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel.
*
* Copyright (C) 2018-2024 Alibaba Group Holding Ltd.
*/

package org.apache.fesod.sheet.converter;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.fesod.sheet.annotation.ExcelProperty;

/**
* Data model whose field names start with a lower case letter followed by an upper case letter.
*
* <p>Field names such as {@code xRealIp} are common in generated DTOs, for example when a column
* named {@code X_REAL_IP} is converted to camel case. The name kept by the cglib bean map of such a
* field differs from the Java field name, which is why these names are covered explicitly.
*/
@Getter
@Setter
@EqualsAndHashCode
public class CamelCaseFieldData {
@ExcelProperty("name")
private String name;

@ExcelProperty("xRealIp")
private String xRealIp;

@ExcelProperty("pName")
private String pName;

@ExcelProperty("attackType")
private String attackType;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/*
* This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel.
*
* Copyright (C) 2018-2024 Alibaba Group Holding Ltd.
*/

package org.apache.fesod.sheet.converter;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.apache.fesod.sheet.FesodSheet;
import org.apache.fesod.sheet.testkit.Tags;
import org.apache.fesod.sheet.testkit.base.AbstractExcelTest;
import org.apache.fesod.sheet.testkit.enums.ExcelFormat;
import org.apache.fesod.sheet.testkit.params.ExcelFormatSource;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.params.ParameterizedTest;

/**
* Tests column include/exclude for field names that start with a lower case letter followed by an
* upper case letter, for example {@code xRealIp} or {@code pName}.
*
* <p>The name kept by the internal cglib bean map of such a field is not the Java field name, so
* filtering by field name must not be based on that name.
*/
@Tag(Tags.ROUND_TRIP)
class CamelCaseFieldDataTest extends AbstractExcelTest {

@ParameterizedTest
@ExcelFormatSource
void writeAllCamelCaseFields(ExcelFormat format) throws Exception {
File file = createTempFile(format);
FesodSheet.write(file, CamelCaseFieldData.class).sheet().doWrite(data());
List<Map<Integer, String>> dataMap = FesodSheet.read(file).sheet().doReadSync();
Assertions.assertEquals(1, dataMap.size());
Map<Integer, String> record = dataMap.get(0);
Assertions.assertEquals(4, record.size());
Assertions.assertEquals("name1", record.get(0));
Assertions.assertEquals("xRealIp1", record.get(1));
Assertions.assertEquals("pName1", record.get(2));
Assertions.assertEquals("attackType1", record.get(3));
}

@ParameterizedTest
@ExcelFormatSource
void writeHeadOfCamelCaseFields(ExcelFormat format) throws Exception {
File file = createTempFile(format);
FesodSheet.write(file, CamelCaseFieldData.class).sheet().doWrite(data());
List<Map<Integer, String>> dataMap =
FesodSheet.read(file).headRowNumber(0).sheet().doReadSync();
Assertions.assertEquals(2, dataMap.size());
Map<Integer, String> record = dataMap.get(0);
Assertions.assertEquals(4, record.size());
Assertions.assertEquals("name", record.get(0));
Assertions.assertEquals("xRealIp", record.get(1));
Assertions.assertEquals("pName", record.get(2));
Assertions.assertEquals("attackType", record.get(3));
}

@ParameterizedTest
@ExcelFormatSource
void includeColumnFieldNames(ExcelFormat format) throws Exception {
File file = createTempFile(format);
FesodSheet.write(file, CamelCaseFieldData.class)
.includeColumnFieldNames(Arrays.asList("name", "xRealIp", "pName", "attackType"))
.sheet()
.doWrite(data());
List<Map<Integer, String>> dataMap = FesodSheet.read(file).sheet().doReadSync();
Assertions.assertEquals(1, dataMap.size());
Map<Integer, String> record = dataMap.get(0);
Assertions.assertEquals(4, record.size());
Assertions.assertEquals("name1", record.get(0));
Assertions.assertEquals("xRealIp1", record.get(1));
Assertions.assertEquals("pName1", record.get(2));
Assertions.assertEquals("attackType1", record.get(3));
}

@ParameterizedTest
@ExcelFormatSource
void includePartOfCamelCaseFieldNames(ExcelFormat format) throws Exception {
File file = createTempFile(format);
FesodSheet.write(file, CamelCaseFieldData.class)
.includeColumnFieldNames(Arrays.asList("name", "xRealIp"))
.sheet()
.doWrite(data());
List<Map<Integer, String>> dataMap = FesodSheet.read(file).sheet().doReadSync();
Assertions.assertEquals(1, dataMap.size());
Map<Integer, String> record = dataMap.get(0);
Assertions.assertEquals(2, record.size());
Assertions.assertEquals("name1", record.get(0));
Assertions.assertEquals("xRealIp1", record.get(1));
}

@ParameterizedTest
@ExcelFormatSource
void excludeCamelCaseFieldNames(ExcelFormat format) throws Exception {
File file = createTempFile(format);
FesodSheet.write(file, CamelCaseFieldData.class)
.excludeColumnFieldNames(Arrays.asList("xRealIp", "attackType"))
.sheet()
.doWrite(data());
List<Map<Integer, String>> dataMap = FesodSheet.read(file).sheet().doReadSync();
Assertions.assertEquals(1, dataMap.size());
Map<Integer, String> record = dataMap.get(0);
Assertions.assertEquals(2, record.size());
Assertions.assertEquals("name1", record.get(0));
Assertions.assertEquals("pName1", record.get(1));
}

@ParameterizedTest
@ExcelFormatSource
void includeUnknownColumnFieldName(ExcelFormat format) throws Exception {
File file = createTempFile(format);
FesodSheet.write(file, CamelCaseFieldData.class)
.includeColumnFieldNames(Arrays.asList("name", "notExist", "pName"))
.sheet()
.doWrite(data());
List<Map<Integer, String>> dataMap = FesodSheet.read(file).sheet().doReadSync();
Assertions.assertEquals(1, dataMap.size());
Map<Integer, String> record = dataMap.get(0);
Assertions.assertEquals(2, record.size());
Assertions.assertEquals("name1", record.get(0));
Assertions.assertEquals("pName1", record.get(1));
}

@ParameterizedTest
@ExcelFormatSource
void includeUnknownColumnFieldNameOrderByIncludeColumn(ExcelFormat format) throws Exception {
File file = createTempFile(format);
FesodSheet.write(file, CamelCaseFieldData.class)
.includeColumnFieldNames(Arrays.asList("name", "notExist", "pName"))
.orderByIncludeColumn(true)
.sheet()
.doWrite(data());
List<Map<Integer, String>> dataMap = FesodSheet.read(file).sheet().doReadSync();
Assertions.assertEquals(1, dataMap.size());
Map<Integer, String> record = dataMap.get(0);
Assertions.assertEquals(2, record.size());
Assertions.assertEquals("name1", record.get(0));
Assertions.assertEquals("pName1", record.get(1));
}

private List<CamelCaseFieldData> data() {
List<CamelCaseFieldData> list = new ArrayList<CamelCaseFieldData>();
CamelCaseFieldData data = new CamelCaseFieldData();
data.setName("name1");
data.setXRealIp("xRealIp1");
data.setPName("pName1");
data.setAttackType("attackType1");
list.add(data);
return list;
}
}
Loading