This is an automated email from the ASF dual-hosted git repository.

pkarwasz pushed a commit to branch feat/archive-builders
in repository https://gitbox.apache.org/repos/asf/commons-compress.git

commit d4bcf0e7754bef7cbde7a85ef3fd0de058648db1
Author: Piotr P. Karwasz <pkarwasz-git...@apache.org>
AuthorDate: Fri Sep 12 18:37:47 2025 +0200

    feat: add builder for `CpioArchiveInputStream`
    
    Introduce a builder for `CpioArchiveInputStream` and refactor existing
    constructor calls to use it.
---
 .../compress/archivers/ArchiveStreamFactory.java   |  5 +-
 .../archivers/cpio/CpioArchiveInputStream.java     | 79 +++++++++++++++++++---
 .../archivers/cpio/CpioArchiveOutputStream.java    |  4 +-
 .../commons/compress/archivers/cpio/CpioUtil.java  |  3 +-
 .../commons/compress/archivers/CpioTest.java       | 10 +--
 .../archivers/cpio/CpioArchiveInputStreamTest.java | 31 +++++----
 .../cpio/CpioArchiveOutputStreamTest.java          |  2 +-
 .../compress/archivers/cpio/CpioArchiveTest.java   | 18 +++--
 8 files changed, 111 insertions(+), 41 deletions(-)

diff --git 
a/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java 
b/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java
index 8559b8bd1..64b76288f 100644
--- 
a/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java
+++ 
b/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java
@@ -458,10 +458,11 @@ public <I extends ArchiveInputStream<? extends 
ArchiveEntry>> I createArchiveInp
                 return (I) new JarArchiveInputStream(in);
             }
             if (CPIO.equalsIgnoreCase(archiverName)) {
+                final CpioArchiveInputStream.Builder cpioBuilder = 
CpioArchiveInputStream.builder().setInputStream(in);
                 if (actualEncoding != null) {
-                    return (I) new CpioArchiveInputStream(in, actualEncoding);
+                    cpioBuilder.setCharset(actualEncoding);
                 }
-                return (I) new CpioArchiveInputStream(in);
+                return (I) cpioBuilder.get();
             }
             if (DUMP.equalsIgnoreCase(archiverName)) {
                 if (actualEncoding != null) {
diff --git 
a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java
 
b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java
index 85c137725..e2008005b 100644
--- 
a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java
+++ 
b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java
@@ -64,6 +64,48 @@
  */
 public class CpioArchiveInputStream extends 
ArchiveInputStream<CpioArchiveEntry> implements CpioConstants {
 
+    /**
+     * Builds a new {@link CpioArchiveInputStream}.
+     * <p>
+     *     For example:
+     * </p>
+     * <pre>{@code
+     * CpioArchiveInputStream in = CpioArchiveInputStream.builder()
+     *     .setBlockSize(1024)
+     *     .setPath(inputPath)
+     *     .setCharset(StandardCharsets.UTF_8)
+     *     .get();
+     * }</pre>
+     * @since 1.29.0
+     */
+    public static final class Builder extends 
ArchiveInputStream.Builder<CpioArchiveInputStream, Builder> {
+
+        private int blockSize = BLOCK_SIZE;
+
+        private Builder() {
+            setCharset(CpioUtil.DEFAULT_CHARSET);
+        }
+
+        /**
+         * Sets the block size of the archive.
+         * <p>
+         *     Default value is {@value CpioConstants#BLOCK_SIZE}.
+         * </p>
+         *
+         * @param blockSize The block size must be bigger than 0
+         * @return this
+         */
+        public Builder setBlockSize(final int blockSize) {
+            this.blockSize = blockSize;
+            return asThis();
+        }
+
+        @Override
+        public CpioArchiveInputStream get() throws IOException {
+            return new CpioArchiveInputStream(this);
+        }
+    }
+
     /**
      * Checks if the signature matches one of the following magic values:
      *
@@ -117,6 +159,16 @@ public static boolean matches(final byte[] signature, 
final int length) {
         return false;
     }
 
+    /**
+     * Creates a new builder.
+     *
+     * @return A new builder
+     * @since 1.29.0
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
     private boolean closed;
 
     private CpioArchiveEntry entry;
@@ -150,7 +202,7 @@ public static boolean matches(final byte[] signature, final 
int length) {
      * @param in The cpio stream
      */
     public CpioArchiveInputStream(final InputStream in) {
-        this(in, BLOCK_SIZE, CpioUtil.DEFAULT_CHARSET_NAME);
+        this(in, builder());
     }
 
     /**
@@ -161,7 +213,7 @@ public CpioArchiveInputStream(final InputStream in) {
      * @since 1.5
      */
     public CpioArchiveInputStream(final InputStream in, final int blockSize) {
-        this(in, blockSize, CpioUtil.DEFAULT_CHARSET_NAME);
+        this(in, builder().setBlockSize(blockSize));
     }
 
     /**
@@ -174,13 +226,7 @@ public CpioArchiveInputStream(final InputStream in, final 
int blockSize) {
      * @since 1.6
      */
     public CpioArchiveInputStream(final InputStream in, final int blockSize, 
final String encoding) {
-        super(in, encoding);
-        this.in = in;
-        if (blockSize <= 0) {
-            throw new IllegalArgumentException("blockSize must be bigger than 
0");
-        }
-        this.blockSize = blockSize;
-        this.zipEncoding = ZipEncodingHelper.getZipEncoding(encoding);
+        this(in, builder().setBlockSize(blockSize).setCharset(encoding));
     }
 
     /**
@@ -191,7 +237,20 @@ public CpioArchiveInputStream(final InputStream in, final 
int blockSize, final S
      * @since 1.6
      */
     public CpioArchiveInputStream(final InputStream in, final String encoding) 
{
-        this(in, BLOCK_SIZE, encoding);
+        this(in, builder().setCharset(encoding));
+    }
+
+    private CpioArchiveInputStream(final Builder builder) throws IOException {
+        this(builder.getInputStream(), builder);
+    }
+
+    private CpioArchiveInputStream(final InputStream in, final Builder 
builder) {
+        super(in, builder.getCharset());
+        if (builder.blockSize <= 0) {
+            throw new IllegalArgumentException("blockSize must be bigger than 
0");
+        }
+        this.blockSize = builder.blockSize;
+        this.zipEncoding = 
ZipEncodingHelper.getZipEncoding(builder.getCharset());
     }
 
     /**
diff --git 
a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java
 
b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java
index d03e14807..e0e7d2361 100644
--- 
a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java
+++ 
b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java
@@ -116,7 +116,7 @@ public CpioArchiveOutputStream(final OutputStream out) {
      * @param format The format of the stream
      */
     public CpioArchiveOutputStream(final OutputStream out, final short format) 
{
-        this(out, format, BLOCK_SIZE, CpioUtil.DEFAULT_CHARSET_NAME);
+        this(out, format, BLOCK_SIZE, CpioUtil.DEFAULT_CHARSET.name());
     }
 
     /**
@@ -128,7 +128,7 @@ public CpioArchiveOutputStream(final OutputStream out, 
final short format) {
      * @since 1.1
      */
     public CpioArchiveOutputStream(final OutputStream out, final short format, 
final int blockSize) {
-        this(out, format, blockSize, CpioUtil.DEFAULT_CHARSET_NAME);
+        this(out, format, blockSize, CpioUtil.DEFAULT_CHARSET.name());
     }
 
     /**
diff --git 
a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioUtil.java 
b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioUtil.java
index 7c71ee1dd..a43409822 100644
--- a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioUtil.java
+++ b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioUtil.java
@@ -18,6 +18,7 @@
  */
 package org.apache.commons.compress.archivers.cpio;
 
+import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 
@@ -28,7 +29,7 @@
  */
 final class CpioUtil {
 
-    static final String DEFAULT_CHARSET_NAME = 
StandardCharsets.US_ASCII.name();
+    static final Charset DEFAULT_CHARSET = StandardCharsets.US_ASCII;
 
     /**
      * Converts a byte array to a long. Halfwords can be swapped by setting 
swapHalfWord=true.
diff --git a/src/test/java/org/apache/commons/compress/archivers/CpioTest.java 
b/src/test/java/org/apache/commons/compress/archivers/CpioTest.java
index 1168e217f..72efa86a8 100644
--- a/src/test/java/org/apache/commons/compress/archivers/CpioTest.java
+++ b/src/test/java/org/apache/commons/compress/archivers/CpioTest.java
@@ -120,7 +120,7 @@ void testDirectoryEntryFromFile() throws Exception {
             tos.closeArchiveEntry();
         }
         final CpioArchiveEntry entryOut;
-        try (CpioArchiveInputStream tis = new 
CpioArchiveInputStream(Files.newInputStream(archive.toPath()))) {
+        try (CpioArchiveInputStream tis = 
CpioArchiveInputStream.builder().setFile(archive).get()) {
             entryOut = tis.getNextCPIOEntry();
         }
         assertNotNull(entryOut);
@@ -144,7 +144,7 @@ void testExplicitDirectoryEntry() throws Exception {
             tos.closeArchiveEntry();
         }
         final CpioArchiveEntry out;
-        try (CpioArchiveInputStream tis = new 
CpioArchiveInputStream(Files.newInputStream(archive.toPath()))) {
+        try (CpioArchiveInputStream tis = 
CpioArchiveInputStream.builder().setFile(archive).get()) {
             out = tis.getNextCPIOEntry();
         }
         assertNotNull(out);
@@ -168,7 +168,7 @@ void testExplicitFileEntry() throws Exception {
             tos.closeArchiveEntry();
         }
         final CpioArchiveEntry out;
-        try (CpioArchiveInputStream tis = new 
CpioArchiveInputStream(Files.newInputStream(archive.toPath()))) {
+        try (CpioArchiveInputStream tis = 
CpioArchiveInputStream.builder().setFile(archive).get()) {
             out = tis.getNextCPIOEntry();
         }
         assertNotNull(out);
@@ -189,7 +189,7 @@ void testFileEntryFromFile() throws Exception {
             tos.closeArchiveEntry();
         }
         final CpioArchiveEntry out;
-        try (CpioArchiveInputStream tis = new 
CpioArchiveInputStream(Files.newInputStream(archive.toPath()))) {
+        try (CpioArchiveInputStream tis = 
CpioArchiveInputStream.builder().setFile(archive).get()) {
             out = tis.getNextCPIOEntry();
         }
         assertNotNull(out);
@@ -220,7 +220,7 @@ void testSymbolicLinkFileEntry() throws Exception {
             tos.closeArchiveEntry();
         }
         final CpioArchiveEntry entry;
-        try (CpioArchiveInputStream tis = new 
CpioArchiveInputStream(Files.newInputStream(archive.toPath()))) {
+        try (CpioArchiveInputStream tis = 
CpioArchiveInputStream.builder().setFile(archive).get()) {
             entry = tis.getNextEntry();
             assertEquals(nameLink, IOUtils.toString(tis, charset));
         }
diff --git 
a/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStreamTest.java
 
b/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStreamTest.java
index 2a0490909..b8eb5f5f9 100644
--- 
a/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStreamTest.java
+++ 
b/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStreamTest.java
@@ -22,9 +22,7 @@
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 
 import org.apache.commons.compress.AbstractTest;
@@ -52,7 +50,8 @@ void testCpioUnarchive() throws Exception {
         expected.append("<empty/>./test2.xml<?xml version=\"1.0\"?>\n");
         expected.append("<empty/>\n");
         final StringBuilder result = new StringBuilder();
-        try (CpioArchiveInputStream in = new 
CpioArchiveInputStream(newInputStream("bla.cpio"))) {
+        try (CpioArchiveInputStream in =
+                
CpioArchiveInputStream.builder().setURI(getURI("bla.cpio")).get()) {
             CpioArchiveEntry entry;
             while ((entry = in.getNextEntry()) != null) {
                 result.append(entry.getName());
@@ -68,7 +67,9 @@ void testCpioUnarchive() throws Exception {
     @Test
     void testCpioUnarchiveCreatedByRedlineRpm() throws Exception {
         long count = 0;
-        try (CpioArchiveInputStream in = new 
CpioArchiveInputStream(newInputStream("redline.cpio"))) {
+        try (CpioArchiveInputStream in = CpioArchiveInputStream.builder()
+                .setURI(getURI("redline.cpio"))
+                .get()) {
             count = consumeEntries(in);
         }
         assertEquals(count, 1);
@@ -77,7 +78,10 @@ void testCpioUnarchiveCreatedByRedlineRpm() throws Exception 
{
     @Test
     void testCpioUnarchiveMultibyteCharName() throws Exception {
         long count = 0;
-        try (CpioArchiveInputStream in = new 
CpioArchiveInputStream(newInputStream("COMPRESS-459.cpio"), 
StandardCharsets.UTF_8.name())) {
+        try (CpioArchiveInputStream in = CpioArchiveInputStream.builder()
+                .setURI(getURI("COMPRESS-459.cpio"))
+                .setCharset(StandardCharsets.UTF_8)
+                .get()) {
             count = consumeEntries(in);
         }
         assertEquals(2, count);
@@ -105,7 +109,7 @@ void testEndOfFileInEntry_c_namesize_0x7FFFFFFF() throws 
Exception {
         // @formatter:on
         final byte[] data = new 
byte[header.getBytes(StandardCharsets.US_ASCII).length + 1];
         System.arraycopy(header.getBytes(), 0, data, 0, 
header.getBytes().length);
-        try (CpioArchiveInputStream cpio = new CpioArchiveInputStream(new 
ByteArrayInputStream(data))) {
+        try (CpioArchiveInputStream cpio = 
CpioArchiveInputStream.builder().setByteArray(data).get()) {
             assertThrows(MemoryLimitException.class, () -> 
cpio.getNextEntry());
         }
     }
@@ -132,15 +136,16 @@ void testEndOfFileInEntry_c_namesize_0xFFFFFFFF() throws 
Exception {
         // @formatter:on
         final byte[] data = new 
byte[header.getBytes(StandardCharsets.US_ASCII).length + 1];
         System.arraycopy(header.getBytes(), 0, data, 0, 
header.getBytes().length);
-        try (CpioArchiveInputStream cpio = new CpioArchiveInputStream(new 
ByteArrayInputStream(data))) {
+        try (CpioArchiveInputStream cpio = 
CpioArchiveInputStream.builder().setByteArray(data).get()) {
             assertThrows(ArchiveException.class, () -> cpio.getNextEntry());
         }
     }
 
     @Test
     void testInvalidLongValueInMetadata() throws Exception {
-        try (InputStream in = 
newInputStream("org/apache/commons/compress/cpio/bad_long_value.cpio");
-             CpioArchiveInputStream archive = new CpioArchiveInputStream(in)) {
+        try (CpioArchiveInputStream archive = CpioArchiveInputStream.builder()
+                
.setURI(getURI("org/apache/commons/compress/cpio/bad_long_value.cpio"))
+                .get()) {
             assertThrows(IOException.class, archive::getNextEntry);
         }
     }
@@ -148,8 +153,8 @@ void testInvalidLongValueInMetadata() throws Exception {
     @Test
     void testMultiByteReadConsistentlyReturnsMinusOneAtEof() throws Exception {
         final byte[] buf = new byte[2];
-        try (InputStream in = newInputStream("bla.cpio");
-                CpioArchiveInputStream archive = new 
CpioArchiveInputStream(in)) {
+        try (CpioArchiveInputStream archive =
+                     
CpioArchiveInputStream.builder().setURI(getURI("bla.cpio")).get()) {
             assertNotNull(archive.getNextEntry());
             IOUtils.toByteArray(archive);
             assertEquals(-1, archive.read(buf));
@@ -159,8 +164,8 @@ void testMultiByteReadConsistentlyReturnsMinusOneAtEof() 
throws Exception {
 
     @Test
     void testSingleByteReadConsistentlyReturnsMinusOneAtEof() throws Exception 
{
-        try (InputStream in = newInputStream("bla.cpio");
-                CpioArchiveInputStream archive = new 
CpioArchiveInputStream(in)) {
+        try (CpioArchiveInputStream archive =
+                
CpioArchiveInputStream.builder().setURI(getURI("bla.cpio")).get()) {
             assertNotNull(archive.getNextEntry());
             IOUtils.toByteArray(archive);
             assertEquals(-1, archive.read());
diff --git 
a/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStreamTest.java
 
b/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStreamTest.java
index 1dfc94371..7ec8d49bf 100644
--- 
a/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStreamTest.java
+++ 
b/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStreamTest.java
@@ -42,7 +42,7 @@ void testWriteOldBinary() throws Exception {
             outputStream.closeArchiveEntry();
         }
         assertTrue(ref.isClosed());
-        try (CpioArchiveInputStream in = new 
CpioArchiveInputStream(Files.newInputStream(output.toPath()))) {
+        try (CpioArchiveInputStream in = 
CpioArchiveInputStream.builder().setFile(output).get()) {
             final CpioArchiveEntry e = in.getNextCPIOEntry();
             assertEquals("test1.xml", e.getName());
             assertNull(in.getNextEntry());
diff --git 
a/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveTest.java 
b/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveTest.java
index 805a0cef5..6df89bb2c 100644
--- 
a/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveTest.java
+++ 
b/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveTest.java
@@ -22,7 +22,6 @@
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 
-import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.stream.Stream;
@@ -50,8 +49,10 @@ void utf18RoundtripTestCtor2() throws Exception {
                 os.closeArchiveEntry();
             }
             baos.close();
-            try (ByteArrayInputStream bin = new 
ByteArrayInputStream(baos.toByteArray());
-                    CpioArchiveInputStream in = new 
CpioArchiveInputStream(bin, StandardCharsets.UTF_8.name())) {
+            try (CpioArchiveInputStream in = CpioArchiveInputStream.builder()
+                    .setByteArray(baos.toByteArray())
+                    .setCharset(StandardCharsets.UTF_8)
+                    .get()) {
                 final CpioArchiveEntry entry = in.getNextEntry();
                 assertNotNull(entry);
                 assertEquals("Test.txt", entry.getName());
@@ -74,8 +75,9 @@ public void utf18RoundtripTestCtor3(final short format) 
throws Exception {
                 os.closeArchiveEntry();
             }
             baos.close();
-            try (ByteArrayInputStream bin = new 
ByteArrayInputStream(baos.toByteArray());
-                    CpioArchiveInputStream in = new 
CpioArchiveInputStream(bin)) {
+            try (CpioArchiveInputStream in = CpioArchiveInputStream.builder()
+                    .setByteArray(baos.toByteArray())
+                    .get()) {
                 final CpioArchiveEntry entry = in.getNextEntry();
                 assertNotNull(entry);
                 assertEquals("T%U00E4st.txt", entry.getName());
@@ -98,8 +100,10 @@ public void utf18RoundtripTestCtor4(final short format) 
throws Exception {
                 os.closeArchiveEntry();
             }
             baos.close();
-            try (ByteArrayInputStream bin = new 
ByteArrayInputStream(baos.toByteArray());
-                    CpioArchiveInputStream in = new 
CpioArchiveInputStream(bin, StandardCharsets.UTF_16LE.name())) {
+            try (CpioArchiveInputStream in = CpioArchiveInputStream.builder()
+                    .setByteArray(baos.toByteArray())
+                    .setCharset(StandardCharsets.UTF_16LE)
+                    .get()) {
                 final CpioArchiveEntry entry = in.getNextEntry();
                 assertNotNull(entry);
                 assertEquals("T\u00e4st.txt", entry.getName());

Reply via email to