This is an automated email from the ASF dual-hosted git repository.
delei pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fesod.git
The following commit(s) were added to refs/heads/main by this push:
new 9db05539 fix: support immutable lists in dynamic header (#668)
9db05539 is described below
commit 9db0553978b7bca0db4e579892943bcc49e31f10
Author: Bengbengbalabalabeng
<[email protected]>
AuthorDate: Fri Feb 27 10:07:25 2026 +0800
fix: support immutable lists in dynamic header (#668)
* fix: support immutable lists in dynamic header
This prevents UnsupportedOperationException when using immutable lists such
as Arrays.asList、List.of or Collections.unmodifiableList ...
* test: update test based on review feedback.
- Use English to describe
- Avoid use imports *
* refactor: replace stream implementation with explicit loop, and update
JavaDoc.
* chore: remove unnecessary imports.
---------
Co-authored-by: ian zhang <[email protected]>
Co-authored-by: Shuxin Pan <[email protected]>
Co-authored-by: DeleiGuo <[email protected]>
---
.../sheet/metadata/AbstractParameterBuilder.java | 20 +++-
.../sheet/head/ImmutableListHeadDataListener.java | 64 +++++++++++++
.../sheet/head/ImmutableListHeadDataTest.java | 102 +++++++++++++++++++++
.../head/ImmutableListHeadDataWriteHandler.java | 39 ++++++++
4 files changed, 224 insertions(+), 1 deletion(-)
diff --git
a/fesod-sheet/src/main/java/org/apache/fesod/sheet/metadata/AbstractParameterBuilder.java
b/fesod-sheet/src/main/java/org/apache/fesod/sheet/metadata/AbstractParameterBuilder.java
index 7e613674..46294306 100644
---
a/fesod-sheet/src/main/java/org/apache/fesod/sheet/metadata/AbstractParameterBuilder.java
+++
b/fesod-sheet/src/main/java/org/apache/fesod/sheet/metadata/AbstractParameterBuilder.java
@@ -19,6 +19,7 @@
package org.apache.fesod.sheet.metadata;
+import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
@@ -39,10 +40,27 @@ public abstract class AbstractParameterBuilder<T extends
AbstractParameterBuilde
* @return
*/
public T head(List<List<String>> head) {
- parameter().setHead(head);
+ parameter().setHead(toMutableListIfNecessary(head));
return self();
}
+ /**
+ * Ensures and returns a mutable head list.
+ *
+ * @param head The source list to create a mutable from.
+ * @return A new mutable list, or the original list if the input is null
or empty.
+ */
+ private List<List<String>> toMutableListIfNecessary(List<List<String>>
head) {
+ if (null == head || head.isEmpty()) {
+ return head;
+ }
+ List<List<String>> result = new ArrayList<>();
+ for (List<String> headColumn : head) {
+ result.add(new ArrayList<>(headColumn));
+ }
+ return result;
+ }
+
/**
* You can only choose one of the {@link #head(List)} and {@link
#head(Class)}
*
diff --git
a/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataListener.java
b/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataListener.java
new file mode 100644
index 00000000..e8c341e6
--- /dev/null
+++
b/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataListener.java
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+package org.apache.fesod.sheet.head;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.apache.fesod.sheet.context.AnalysisContext;
+import org.apache.fesod.sheet.metadata.data.ReadCellData;
+import org.apache.fesod.sheet.read.listener.ReadListener;
+import org.junit.jupiter.api.Assertions;
+
+public class ImmutableListHeadDataListener implements
ReadListener<Map<Integer, String>> {
+
+ private List<Map<Integer, String>> list = new ArrayList<Map<Integer,
String>>();
+
+ @Override
+ public void invokeHead(Map<Integer, ReadCellData<?>> headMap,
AnalysisContext context) {
+ Assertions.assertNotNull(context.readRowHolder().getRowIndex());
+ headMap.forEach((key, value) -> {
+ Assertions.assertEquals(value.getRowIndex(),
context.readRowHolder().getRowIndex());
+ Assertions.assertEquals(value.getColumnIndex(), key);
+ });
+ }
+
+ @Override
+ public void invoke(Map<Integer, String> data, AnalysisContext context) {
+ list.add(data);
+ }
+
+ @Override
+ public void doAfterAllAnalysed(AnalysisContext context) {
+ List<List<String>> head = context.readSheetHolder().getHead();
+
+ Assertions.assertInstanceOf(ArrayList.class, head);
+ for (List<String> item : head) {
+ Assertions.assertInstanceOf(ArrayList.class, item);
+ }
+
+ Assertions.assertEquals(1, list.size());
+ Map<Integer, String> data = list.get(0);
+ Assertions.assertEquals("stringData", data.get(0));
+ Assertions.assertEquals("1", data.get(1));
+ Assertions.assertEquals("2025-10-31 01:01:01", data.get(2));
+ Assertions.assertEquals("extraData", data.get(3));
+ }
+}
diff --git
a/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataTest.java
b/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataTest.java
new file mode 100644
index 00000000..e97741aa
--- /dev/null
+++
b/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+package org.apache.fesod.sheet.head;
+
+import java.io.File;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.apache.fesod.sheet.FastExcel;
+import org.apache.fesod.sheet.util.DateUtils;
+import org.apache.fesod.sheet.util.TestFileUtil;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class ImmutableListHeadDataTest {
+
+ private static File file07;
+ private static File file03;
+ private static File fileCsv;
+
+ @BeforeAll
+ public static void init() {
+ file07 = TestFileUtil.createNewFile("listHead07.xlsx");
+ file03 = TestFileUtil.createNewFile("listHead03.xls");
+ fileCsv = TestFileUtil.createNewFile("listHeadCsv.csv");
+ }
+
+ @Test
+ public void t01ReadAndWrite07() throws Exception {
+ readAndWrite(file07);
+ }
+
+ @Test
+ public void t02ReadAndWrite03() throws Exception {
+ readAndWrite(file03);
+ }
+
+ @Test
+ public void t03ReadAndWriteCsv() throws Exception {
+ readAndWrite(fileCsv);
+ }
+
+ private void readAndWrite(File file) throws Exception {
+ FastExcel.write(file)
+ .head(head())
+ .registerWriteHandler(new ImmutableListHeadDataWriteHandler())
+ .sheet()
+ .doWrite(data());
+
+ FastExcel.read(file)
+ .head(head())
+ .registerReadListener(new ImmutableListHeadDataListener())
+ .sheet()
+ .doRead();
+ }
+
+ private List<List<String>> head() {
+ List<List<String>> list = new ArrayList<List<String>>();
+ List<String> head0 = Arrays.asList("stringTitle");
+ List<String> head1 = new ArrayList<String>();
+ head1.add("numberTitle1");
+ head1.add("numberTitle2");
+
+ list.add(head0);
+ list.add(Collections.unmodifiableList(head1));
+ list.add(Collections.singletonList("datetimeTitle"));
+ return list;
+ }
+
+ private List<List<Object>> data() throws ParseException {
+ List<List<Object>> list = new ArrayList<List<Object>>();
+ List<Object> data0 = new ArrayList<Object>();
+ data0.add("stringData");
+ data0.add(1);
+ data0.add(DateUtils.parseDate("2025-10-31 01:01:01"));
+ data0.add("extraData");
+ list.add(data0);
+ return list;
+ }
+}
diff --git
a/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataWriteHandler.java
b/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataWriteHandler.java
new file mode 100644
index 00000000..3975a32f
--- /dev/null
+++
b/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataWriteHandler.java
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+package org.apache.fesod.sheet.head;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.fesod.sheet.write.handler.SheetWriteHandler;
+import org.apache.fesod.sheet.write.handler.context.SheetWriteHandlerContext;
+import org.junit.jupiter.api.Assertions;
+
+public class ImmutableListHeadDataWriteHandler implements SheetWriteHandler {
+
+ @Override
+ public void afterSheetDispose(SheetWriteHandlerContext context) {
+ List<List<String>> head =
context.getWriteContext().writeSheetHolder().getHead();
+
+ Assertions.assertInstanceOf(ArrayList.class, head);
+ for (List<String> item : head) {
+ Assertions.assertInstanceOf(ArrayList.class, item);
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]