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-fileupload.git
The following commit(s) were added to refs/heads/master by this push: new 3791bed Use a builder 3791bed is described below commit 3791bedb93a8ed2c6d1b5a82bc8b30afa4757d6c Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Thu Jun 8 19:38:32 2023 -0400 Use a builder --- .../commons/fileupload2/FileItemIteratorImpl.java | 2 +- .../commons/fileupload2/MultipartStream.java | 104 ++++++++++++++++++--- .../commons/fileupload2/MultipartStreamTest.java | 12 ++- 3 files changed, 97 insertions(+), 21 deletions(-) diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/FileItemIteratorImpl.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/FileItemIteratorImpl.java index b446832..c6cc014 100644 --- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/FileItemIteratorImpl.java +++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/FileItemIteratorImpl.java @@ -282,7 +282,7 @@ class FileItemIteratorImpl implements FileItemIterator { progressNotifier = new MultipartStream.ProgressNotifier(fileUploadBase.getProgressListener(), requestSize); try { - multiPartStream = new MultipartStream(input, multiPartBoundary, progressNotifier); + multiPartStream = MultipartStream.builder().setInputStream(input).setBoundary(multiPartBoundary).setProgressNotifier(progressNotifier).get(); } catch (final IllegalArgumentException e) { IOUtils.closeQuietly(input); // avoid possible resource leak throw new FileUploadContentTypeException(String.format("The boundary specified in the %s header is too long", AbstractFileUpload.CONTENT_TYPE), e); diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/MultipartStream.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/MultipartStream.java index 8faa754..445e97b 100644 --- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/MultipartStream.java +++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/MultipartStream.java @@ -21,8 +21,11 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import org.apache.commons.io.IOUtils; +import org.apache.commons.io.build.AbstractOrigin; +import org.apache.commons.io.build.AbstractStreamBuilder; import org.apache.commons.io.output.NullOutputStream; /** @@ -77,7 +80,81 @@ import org.apache.commons.io.output.NullOutputStream; * } * </pre> */ -public class MultipartStream { +public final class MultipartStream { + + /** + * Builds a new {@link MultipartStream} instance. + * <p> + * For example: + * </p> + * + * <pre>{@code + * MultipartStream factory = MultipartStream.builder() + * .setPath(path) + * .setBufferSize(DEFAULT_THRESHOLD) + * .get(); + * } + * </pre> + */ + public static class Builder extends AbstractStreamBuilder<MultipartStream, Builder> { + + /** + * Boundary. + */ + private byte[] boundary; + + /** + * Progress notifier. + */ + private ProgressNotifier progressNotifier; + + public Builder() { + setBufferSizeDefault(DEFAULT_BUFSIZE); + } + + /** + * Constructs a new instance. + * <p> + * This builder uses the InputStream, buffer size, boundary and progress notifier aspects. + * </p> + * <p> + * You must provide an origin that can be converted to a Reader by this builder, otherwise, this call will throw an + * {@link UnsupportedOperationException}. + * </p> + * + * @return a new instance. + * @throws IOException if an I/O error occurs. + * @throws UnsupportedOperationException if the origin cannot provide a Path. + * @see AbstractOrigin#getReader(Charset) + */ + @Override + public MultipartStream get() throws IOException { + return new MultipartStream(getInputStream(), boundary, getBufferSize(), progressNotifier); + } + + /** + * Sets the boundary. + * + * @param boundary the boundary. + * @return this + */ + public Builder setBoundary(final byte[] boundary) { + this.boundary = boundary; + return this; + } + + /** + * Sets the progress notifier. + * + * @param progressNotifier progress notifier.. + * @return this + */ + public Builder setProgressNotifier(final ProgressNotifier progressNotifier) { + this.progressNotifier = progressNotifier; + return this; + } + + } /** * Signals an attempt to set an invalid boundary token. @@ -497,6 +574,15 @@ public class MultipartStream { return true; } + /** + * Constructs a new {@link Builder}. + * + * @return a new {@link Builder}. + */ + public static Builder builder() { + return new Builder(); + } + /** * The input stream from which data is read. */ @@ -567,7 +653,7 @@ public class MultipartStream { * @param notifier The notifier, which is used for calling the progress listener, if any. * @throws IllegalArgumentException If the buffer size is too small. */ - public MultipartStream(final InputStream input, final byte[] boundary, final int bufferSize, final ProgressNotifier notifier) { + private MultipartStream(final InputStream input, final byte[] boundary, final int bufferSize, final ProgressNotifier notifier) { if (boundary == null) { throw new IllegalArgumentException("boundary may not be null"); } @@ -595,18 +681,6 @@ public class MultipartStream { tail = 0; } - /** - * Constructs a {@code MultipartStream} with a default size buffer. - * - * @param input The {@code InputStream} to serve as a data source. - * @param boundary The token used for dividing the stream into {@code encapsulations}. - * @param progressNotifier An object for calling the progress listener, if any. - * @see #MultipartStream(InputStream, byte[], int, ProgressNotifier) - */ - public MultipartStream(final InputStream input, final byte[] boundary, final ProgressNotifier progressNotifier) { - this(input, boundary, DEFAULT_BUFSIZE, progressNotifier); - } - /** * Computes the table used for Knuth-Morris-Pratt search algorithm. */ @@ -707,7 +781,7 @@ public class MultipartStream { * Reads {@code body-data} from the current {@code encapsulation} and writes its contents into the output {@code Stream}. * <p> * Arbitrary large amounts of data can be processed by this method using a constant size buffer. (see - * {@link #MultipartStream(InputStream,byte[],int, MultipartStream.ProgressNotifier) constructor}). + * {@link MultipartStream#builder()}). * </p> * * @param output The {@code Stream} to write data into. May be null, in which case this method is equivalent to {@link #discardBodyData()}. diff --git a/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/MultipartStreamTest.java b/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/MultipartStreamTest.java index a77560b..d850141 100644 --- a/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/MultipartStreamTest.java +++ b/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/MultipartStreamTest.java @@ -25,7 +25,7 @@ import java.io.InputStream; import org.junit.jupiter.api.Test; /** - * Unit tests {@link org.apache.commons.fileupload2.MultipartStream}. + * Unit tests {@link MultipartStream}. */ public class MultipartStreamTest { @@ -38,8 +38,8 @@ public class MultipartStreamTest { final InputStream input = new ByteArrayInputStream(contents); final byte[] boundary = BOUNDARY_TEXT.getBytes(); final int iBufSize = 1; - assertThrows(IllegalArgumentException.class, - () -> new MultipartStream(input, boundary, iBufSize, new MultipartStream.ProgressNotifier(null, contents.length))); + assertThrows(IllegalArgumentException.class, () -> MultipartStream.builder().setInputStream(input).setBoundary(boundary).setBufferSize(iBufSize) + .setProgressNotifier(new MultipartStream.ProgressNotifier(null, contents.length)).get()); } @Test @@ -49,7 +49,8 @@ public class MultipartStreamTest { final InputStream input = new ByteArrayInputStream(contents); final byte[] boundary = BOUNDARY_TEXT.getBytes(); final int iBufSize = boundary.length + MultipartStream.BOUNDARY_PREFIX.length + 1; - final MultipartStream ms = new MultipartStream(input, boundary, iBufSize, new MultipartStream.ProgressNotifier(null, contents.length)); + final MultipartStream ms = MultipartStream.builder().setInputStream(input).setBoundary(boundary).setBufferSize(iBufSize) + .setProgressNotifier(new MultipartStream.ProgressNotifier(null, contents.length)).get(); assertNotNull(ms); } @@ -59,7 +60,8 @@ public class MultipartStreamTest { final byte[] contents = strData.getBytes(); final InputStream input = new ByteArrayInputStream(contents); final byte[] boundary = BOUNDARY_TEXT.getBytes(); - final MultipartStream ms = new MultipartStream(input, boundary, new MultipartStream.ProgressNotifier(null, contents.length)); + final MultipartStream ms = MultipartStream.builder().setInputStream(input).setBoundary(boundary) + .setProgressNotifier(new MultipartStream.ProgressNotifier(null, contents.length)).get(); assertNotNull(ms); }