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]

Reply via email to