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

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git

commit 256436e90a62eb7394b2962c0fba7b4f6e8ab3bf
Author: Gary Gregory <garydgreg...@gmail.com>
AuthorDate: Sat May 20 10:44:57 2023 -0400

    Refactor and pull up CharSequenceInputStream.Builder.setCharSequence()
---
 .../apache/commons/io/build/AbstractOrigin.java    | 44 +++++++++++++++++-
 .../commons/io/build/AbstractOriginSupplier.java   | 45 +++++++++++++-----
 .../commons/io/build/AbstractStreamBuilder.java    | 13 ++++++
 .../commons/io/input/AutoCloseInputStream.java     | 54 ++++++++++++++++++++++
 .../commons/io/input/CharSequenceInputStream.java  | 20 ++------
 .../commons/io/input/AutoCloseInputStreamTest.java | 33 +++++++++++--
 6 files changed, 177 insertions(+), 32 deletions(-)

diff --git a/src/main/java/org/apache/commons/io/build/AbstractOrigin.java 
b/src/main/java/org/apache/commons/io/build/AbstractOrigin.java
index 6624bfb6..da4652ef 100644
--- a/src/main/java/org/apache/commons/io/build/AbstractOrigin.java
+++ b/src/main/java/org/apache/commons/io/build/AbstractOrigin.java
@@ -68,7 +68,37 @@ public abstract class AbstractOrigin<T, B extends 
AbstractOrigin<T, B>> extends
 
         @Override
         public InputStream getInputStream(final OpenOption... options) throws 
IOException {
-            return new ByteArrayInputStream(getByteArray());
+            return new ByteArrayInputStream(origin);
+        }
+
+    }
+
+    /**
+     * A {@link CharSequence} origin.
+     */
+    public static class CharSequenceOrigin extends 
AbstractOrigin<CharSequence, CharSequenceOrigin> {
+
+        /**
+         * Constructs a new instance for the given origin.
+         *
+         * @param origin The origin.
+         */
+        public CharSequenceOrigin(final CharSequence origin) {
+            super(origin);
+        }
+
+        @Override
+        public CharSequence getCharSequence(final Charset charset) {
+            // No conversion
+            return get();
+        }
+
+        @Override
+        public InputStream getInputStream(final OpenOption... options) throws 
IOException {
+            // TODO Pass in a Charset? Consider if call sites actually need 
this.
+            return new 
ByteArrayInputStream(origin.toString().getBytes(Charset.defaultCharset()));
+            // Needs [IO-795] CharSequenceInputStream.reset() only works once.
+            // return 
CharSequenceInputStream.builder().setCharSequence(getCharSequence(Charset.defaultCharset())).get();
         }
 
     }
@@ -292,6 +322,18 @@ public abstract class AbstractOrigin<T, B extends 
AbstractOrigin<T, B>> extends
         return Files.readAllBytes(getPath());
     }
 
+    /**
+     * Gets this origin as a byte array, if possible.
+     *
+     * @param charset The charset to use if conversion from bytes is needed.
+     * @return this origin as a byte array, if possible.
+     * @throws IOException if an I/O error occurs.
+     * @throws UnsupportedOperationException if the origin cannot be converted 
to a Path.
+     */
+    public CharSequence getCharSequence(final Charset charset) throws 
IOException {
+        return new String(getByteArray(), charset);
+    }
+
     /**
      * Gets this origin as a Path, if possible.
      *
diff --git 
a/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java 
b/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java
index 706ec285..ef691f44 100644
--- a/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java
+++ b/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java
@@ -28,6 +28,7 @@ import java.nio.file.Paths;
 import java.util.Objects;
 
 import org.apache.commons.io.build.AbstractOrigin.ByteArrayOrigin;
+import org.apache.commons.io.build.AbstractOrigin.CharSequenceOrigin;
 import org.apache.commons.io.build.AbstractOrigin.FileOrigin;
 import org.apache.commons.io.build.AbstractOrigin.InputStreamOrigin;
 import org.apache.commons.io.build.AbstractOrigin.OutputStreamOrigin;
@@ -48,18 +49,29 @@ public abstract class AbstractOriginSupplier<T, B extends 
AbstractOriginSupplier
     /**
      * Creates a new byte array origin for a byte array.
      *
-     * @param origin the file.
-     * @return a new file origin
+     * @param origin the byte array.
+     * @return a new byte array origin.
      */
     protected static ByteArrayOrigin newByteArrayOrigin(final byte[] origin) {
         return new ByteArrayOrigin(origin);
     }
 
+    /**
+     * Creates a new CharSequence origin for a CharSequence.
+     *
+     * @param origin the CharSequence.
+     * @return a new file origin.
+     * @since 2.13.0
+     */
+    protected static CharSequenceOrigin newCharSequenceOrigin(final 
CharSequence origin) {
+        return new CharSequenceOrigin(origin);
+    }
+
     /**
      * Creates a new file origin for a file.
      *
      * @param origin the file.
-     * @return a new file origin
+     * @return a new file origin.
      */
     protected static FileOrigin newFileOrigin(final File origin) {
         return new FileOrigin(origin);
@@ -69,7 +81,7 @@ public abstract class AbstractOriginSupplier<T, B extends 
AbstractOriginSupplier
      * Creates a new file origin for a file path.
      *
      * @param origin the file path.
-     * @return a new file origin
+     * @return a new file origin.
      */
     protected static FileOrigin newFileOrigin(final String origin) {
         return new FileOrigin(new File(origin));
@@ -79,7 +91,7 @@ public abstract class AbstractOriginSupplier<T, B extends 
AbstractOriginSupplier
      * Creates a new input stream origin for a file.
      *
      * @param origin the input stream.
-     * @return a new input stream origin
+     * @return a new input stream origin.
      */
     protected static InputStreamOrigin newInputStreamOrigin(final InputStream 
origin) {
         return new InputStreamOrigin(origin);
@@ -89,7 +101,7 @@ public abstract class AbstractOriginSupplier<T, B extends 
AbstractOriginSupplier
      * Creates a new output stream origin for a file.
      *
      * @param origin the output stream.
-     * @return a new output stream origin
+     * @return a new output stream origin.
      */
     protected static OutputStreamOrigin newOutputStreamOrigin(final 
OutputStream origin) {
         return new OutputStreamOrigin(origin);
@@ -99,7 +111,7 @@ public abstract class AbstractOriginSupplier<T, B extends 
AbstractOriginSupplier
      * Creates a new path origin for a file.
      *
      * @param origin the path.
-     * @return a new path origin
+     * @return a new path origin.
      */
     protected static PathOrigin newPathOrigin(final Path origin) {
         return new PathOrigin(origin);
@@ -109,7 +121,7 @@ public abstract class AbstractOriginSupplier<T, B extends 
AbstractOriginSupplier
      * Creates a new path name origin for a path name.
      *
      * @param origin the path name.
-     * @return a new path name origin
+     * @return a new path name origin.
      */
     protected static PathOrigin newPathOrigin(final String origin) {
         return new PathOrigin(Paths.get(origin));
@@ -119,7 +131,7 @@ public abstract class AbstractOriginSupplier<T, B extends 
AbstractOriginSupplier
      * Creates a new reader origin for a reader.
      *
      * @param origin the reader.
-     * @return a new reader origin
+     * @return a new reader origin.
      */
     protected static ReaderOrigin newReaderOrigin(final Reader origin) {
         return new ReaderOrigin(origin);
@@ -129,7 +141,7 @@ public abstract class AbstractOriginSupplier<T, B extends 
AbstractOriginSupplier
      * Creates a new reader origin for a URI.
      *
      * @param origin the URI.
-     * @return a new URI origin
+     * @return a new URI origin.
      */
     protected static URIOrigin newURIOrigin(final URI origin) {
         return new URIOrigin(origin);
@@ -139,7 +151,7 @@ public abstract class AbstractOriginSupplier<T, B extends 
AbstractOriginSupplier
      * Creates a new writer origin for a file.
      *
      * @param origin the writer.
-     * @return a new writer origin
+     * @return a new writer .
      */
     protected static WriterOrigin newWriterOrigin(final Writer origin) {
         return new WriterOrigin(origin);
@@ -188,6 +200,17 @@ public abstract class AbstractOriginSupplier<T, B extends 
AbstractOriginSupplier
         return setOrigin(newByteArrayOrigin(origin));
     }
 
+    /**
+     * Sets a new origin.
+     *
+     * @param origin the new origin.
+     * @return this
+     * @since 2.13.0
+     */
+    public B setCharSequence(final CharSequence origin) {
+        return setOrigin(newCharSequenceOrigin(origin));
+    }
+
     /**
      * Sets a new origin.
      *
diff --git 
a/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java 
b/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java
index 3c34689f..3cbe1698 100644
--- a/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java
+++ b/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java
@@ -79,6 +79,19 @@ public abstract class AbstractStreamBuilder<T, B extends 
AbstractStreamBuilder<T
         return bufferSizeDefault;
     }
 
+    /**
+     * Gets a CharSequence from the origin with a Charset.
+     *
+     * @return An input stream
+     * @throws IOException                   if an I/O error occurs.
+     * @throws UnsupportedOperationException if the origin cannot be converted 
to a CharSequence.
+     * @see AbstractOrigin#getCharSequence(Charset)
+     * @since 2.13.0
+     */
+    protected CharSequence getCharSequence() throws IOException {
+        return getOrigin().getCharSequence(getCharset());
+    }
+
     /**
      * Gets the Charset, defaults to {@link Charset#defaultCharset()}.
      *
diff --git 
a/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java 
b/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java
index bf3d317b..05885896 100644
--- a/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java
@@ -21,6 +21,8 @@ import static org.apache.commons.io.IOUtils.EOF;
 import java.io.IOException;
 import java.io.InputStream;
 
+import org.apache.commons.io.build.AbstractStreamBuilder;
+
 /**
  * Proxy stream that closes and discards the underlying stream as soon as the
  * end of input has been reached or when the stream is explicitly closed.
@@ -38,11 +40,63 @@ import java.io.InputStream;
  */
 public class AutoCloseInputStream extends ProxyInputStream {
 
+    /**
+     * Builds a new {@link AutoCloseInputStream} instance.
+     * <p>
+     * For example:
+     * </p>
+     *
+     * <pre>{@code
+     * AutoCloseInputStream s = AutoCloseInputStream.builder()
+     *   .setPath(path)
+     *   .get();}
+     * </pre>
+     *
+     * <pre>{@code
+     * AutoCloseInputStream s = AutoCloseInputStream.builder()
+     *   .setInputStream(inputStream)
+     *   .get();}
+     * </pre>
+     *
+     * @since 2.13.0
+     */
+    public static class Builder extends 
AbstractStreamBuilder<AutoCloseInputStream, Builder> {
+
+        /**
+         * Constructs a new instance.
+         * <p>
+         * This builder use the aspect InputStream.
+         * </p>
+         *
+         * @return a new instance.
+         * @throws IOException              if an I/O error occurs.
+         * @throws IllegalArgumentException if the buffer is not large enough 
to hold a complete character.
+         */
+        @SuppressWarnings("resource") // Caller closes
+        @Override
+        public AutoCloseInputStream get() throws IOException {
+            return new AutoCloseInputStream(getInputStream());
+        }
+
+    }
+
+    /**
+     * Constructs a new {@link Builder}.
+     *
+     * @return a new {@link Builder}.
+     * @since 2.12.0
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
     /**
      * Creates an automatically closing proxy for the given input stream.
      *
      * @param in underlying input stream
+     * @deprecated Use {@link #builder()} and {@link Builder#get()}
      */
+    @Deprecated
     public AutoCloseInputStream(final InputStream in) {
         super(in);
     }
diff --git 
a/src/main/java/org/apache/commons/io/input/CharSequenceInputStream.java 
b/src/main/java/org/apache/commons/io/input/CharSequenceInputStream.java
index 0c340348..1ccde6ad 100644
--- a/src/main/java/org/apache/commons/io/input/CharSequenceInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/CharSequenceInputStream.java
@@ -33,6 +33,7 @@ import java.util.Objects;
 import org.apache.commons.io.Charsets;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.build.AbstractStreamBuilder;
+import org.apache.commons.io.function.Uncheck;
 
 /**
  * Implements an {@link InputStream} to read from String, StringBuffer, 
StringBuilder or CharBuffer.
@@ -62,12 +63,10 @@ public class CharSequenceInputStream extends InputStream {
      */
     public static class Builder extends 
AbstractStreamBuilder<CharSequenceInputStream, Builder> {
 
-        private CharSequence source;
-
         /**
          * Constructs a new instance.
          * <p>
-         * This builder use the aspects the buffer size, CharSequence, and 
Charset.
+         * This builder use the aspects the CharSequence, buffer size, and 
Charset.
          * </p>
          *
          * @return a new instance.
@@ -75,18 +74,7 @@ public class CharSequenceInputStream extends InputStream {
          */
         @Override
         public CharSequenceInputStream get() {
-            return new CharSequenceInputStream(source, getCharset(), 
getBufferSize());
-        }
-
-        /**
-         * Sets the non-null CharSequence.
-         *
-         * @param source The source string, MUST not be null.
-         * @return this.
-         */
-        public Builder setCharSequence(final CharSequence source) {
-            this.source = Objects.requireNonNull(source, "source");
-            return this;
+            return Uncheck.get(() -> new 
CharSequenceInputStream(getCharSequence(), getCharset(), getBufferSize()));
         }
 
     }
@@ -292,7 +280,7 @@ public class CharSequenceInputStream extends InputStream {
         //
         // Since the bBuf is re-used, in general it's necessary to re-encode 
the data.
         //
-        // It should be possible to apply some optimisations however:
+        // It should be possible to apply some optimizations however:
         // + use mark/reset on the cBuf and bBuf. This would only work if the 
buffer had not been (re)filled since
         // the mark. The code would have to catch InvalidMarkException - does 
not seem possible to check if mark is
         // valid otherwise. + Try saving the state of the cBuf before each 
fillBuffer; it might be possible to
diff --git 
a/src/test/java/org/apache/commons/io/input/AutoCloseInputStreamTest.java 
b/src/test/java/org/apache/commons/io/input/AutoCloseInputStreamTest.java
index 455db058..ca67b2b5 100644
--- a/src/test/java/org/apache/commons/io/input/AutoCloseInputStreamTest.java
+++ b/src/test/java/org/apache/commons/io/input/AutoCloseInputStreamTest.java
@@ -39,7 +39,7 @@ public class AutoCloseInputStreamTest {
 
     @BeforeEach
     public void setUp() {
-        data = new byte[] {'x', 'y', 'z'};
+        data = new byte[] { 'x', 'y', 'z' };
         stream = new AutoCloseInputStream(new ByteArrayInputStream(data) {
             @Override
             public void close() {
@@ -106,9 +106,34 @@ public class AutoCloseInputStreamTest {
     }
 
     @Test
-    public void testResetBeforeEnd() throws IOException {
-        final String inputStr = "1234";
-        final AutoCloseInputStream inputStream = new AutoCloseInputStream(new 
ByteArrayInputStream(inputStr.getBytes()));
+    public void testResetBeforeEndCtor() throws IOException {
+        try (final AutoCloseInputStream inputStream = new 
AutoCloseInputStream(new ByteArrayInputStream("1234".getBytes()))) {
+            testResetBeforeEnd(inputStream);
+        }
+    }
+
+    @Test
+    public void testResetBeforeEndSetInputStream() throws IOException {
+        try (final AutoCloseInputStream inputStream = 
AutoCloseInputStream.builder().setInputStream(new 
ByteArrayInputStream("1234".getBytes())).get()) {
+            testResetBeforeEnd(inputStream);
+        }
+    }
+
+    @Test
+    public void testResetBeforeEndSetByteArray() throws IOException {
+        try (final AutoCloseInputStream inputStream = 
AutoCloseInputStream.builder().setByteArray("1234".getBytes()).get()) {
+            testResetBeforeEnd(inputStream);
+        }
+    }
+
+    @Test
+    public void testResetBeforeEndSetCharSequence() throws IOException {
+        try (final AutoCloseInputStream inputStream = 
AutoCloseInputStream.builder().setCharSequence("1234").get()) {
+            testResetBeforeEnd(inputStream);
+        }
+    }
+
+    private void testResetBeforeEnd(final AutoCloseInputStream inputStream) 
throws IOException {
         inputStream.mark(1);
         assertEquals('1', inputStream.read());
         inputStream.reset();

Reply via email to