PR: FILEUPLOAD-300
Move FileItemIteratorImpl class to item package.
diff --git a/src/main/java/org/apache/commons/fileupload2/FileUploadBase.java b/src/main/java/org/apache/commons/fileupload2/FileUploadBase.java
index 0a3a19b..4ba37ac 100644
--- a/src/main/java/org/apache/commons/fileupload2/FileUploadBase.java
+++ b/src/main/java/org/apache/commons/fileupload2/FileUploadBase.java
@@ -19,7 +19,6 @@
import static java.lang.String.format;
import java.io.IOException;
-import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -27,17 +26,15 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
-import java.util.NoSuchElementException;
import javax.servlet.http.HttpServletRequest;
+import org.apache.commons.fileupload2.impl.FileItemIteratorImpl;
import org.apache.commons.fileupload2.impl.FileItemStreamImpl;
import org.apache.commons.fileupload2.servlet.ServletFileUpload;
import org.apache.commons.fileupload2.servlet.ServletRequestContext;
import org.apache.commons.fileupload2.util.FileItemHeadersImpl;
-import org.apache.commons.fileupload2.util.LimitedInputStream;
import org.apache.commons.fileupload2.util.Streams;
-import org.apache.commons.io.IOUtils;
/**
* <p>High level API for processing file uploads.</p>
@@ -415,7 +412,7 @@
*
* @return The boundary, as a byte array.
*/
- protected byte[] getBoundary(String contentType) {
+ public byte[] getBoundary(String contentType) {
ParameterParser parser = new ParameterParser();
parser.setLowerCaseNames(true);
// Parameter parser can handle null input
@@ -456,7 +453,7 @@
*
* @return The file name for the current <code>encapsulation</code>.
*/
- protected String getFileName(FileItemHeaders headers) {
+ public String getFileName(FileItemHeaders headers) {
return getFileName(headers.getHeader(CONTENT_DISPOSITION));
}
@@ -498,7 +495,7 @@
*
* @return The field name for the current <code>encapsulation</code>.
*/
- protected String getFieldName(FileItemHeaders headers) {
+ public String getFieldName(FileItemHeaders headers) {
return getFieldName(headers.getHeader(CONTENT_DISPOSITION));
}
@@ -574,7 +571,7 @@
*
* @return A <code>Map</code> containing the parsed HTTP request headers.
*/
- protected FileItemHeaders getParsedHeaders(String headerPart) {
+ public FileItemHeaders getParsedHeaders(String headerPart) {
final int len = headerPart.length();
FileItemHeadersImpl headers = newFileItemHeaders();
int start = 0;
@@ -702,315 +699,6 @@
}
/**
- * The iterator, which is returned by
- * {@link FileUploadBase#getItemIterator(RequestContext)}.
- */
- public static class FileItemIteratorImpl implements FileItemIterator {
- private final FileUploadBase fileUploadBase;
- private final RequestContext ctx;
- private long sizeMax, fileSizeMax;
-
-
- @Override
- public long getSizeMax() {
- return sizeMax;
- }
-
- @Override
- public void setSizeMax(long sizeMax) {
- this.sizeMax = sizeMax;
- }
-
- @Override
- public long getFileSizeMax() {
- return fileSizeMax;
- }
-
- @Override
- public void setFileSizeMax(long fileSizeMax) {
- this.fileSizeMax = fileSizeMax;
- }
-
- /**
- * The multi part stream to process.
- */
- private MultipartStream multiPartStream;
-
- /**
- * The notifier, which used for triggering the
- * {@link ProgressListener}.
- */
- private MultipartStream.ProgressNotifier progressNotifier;
-
- /**
- * The boundary, which separates the various parts.
- */
- private byte[] multiPartBoundary;
-
- /**
- * The item, which we currently process.
- */
- private FileItemStreamImpl currentItem;
-
- /**
- * The current items field name.
- */
- private String currentFieldName;
-
- /**
- * Whether we are currently skipping the preamble.
- */
- private boolean skipPreamble;
-
- /**
- * Whether the current item may still be read.
- */
- private boolean itemValid;
-
- /**
- * Whether we have seen the end of the file.
- */
- private boolean eof;
-
- /**
- * Creates a new instance.
- *
- * @param ctx The request context.
- * @throws FileUploadException An error occurred while
- * parsing the request.
- * @throws IOException An I/O error occurred.
- */
- FileItemIteratorImpl(FileUploadBase pFileUploadBase, RequestContext pRequestContext)
- throws FileUploadException, IOException {
- fileUploadBase = pFileUploadBase;
- sizeMax = fileUploadBase.getSizeMax();
- fileSizeMax = fileUploadBase.getFileSizeMax();
- ctx = pRequestContext;
- if (ctx == null) {
- throw new NullPointerException("ctx parameter");
- }
-
-
- skipPreamble = true;
- findNextItem();
- }
-
- protected void init(FileUploadBase fileUploadBase, RequestContext pRequestContext)
- throws FileUploadException, IOException {
- String contentType = ctx.getContentType();
- if ((null == contentType)
- || (!contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART))) {
- throw new InvalidContentTypeException(
- format("the request doesn't contain a %s or %s stream, content type header is %s",
- MULTIPART_FORM_DATA, MULTIPART_MIXED, contentType));
- }
-
-
- @SuppressWarnings("deprecation") // still has to be backward compatible
- final int contentLengthInt = ctx.getContentLength();
-
- final long requestSize = UploadContext.class.isAssignableFrom(ctx.getClass())
- // Inline conditional is OK here CHECKSTYLE:OFF
- ? ((UploadContext) ctx).contentLength()
- : contentLengthInt;
- // CHECKSTYLE:ON
-
- InputStream input; // N.B. this is eventually closed in MultipartStream processing
- if (sizeMax >= 0) {
- if (requestSize != -1 && requestSize > sizeMax) {
- throw new SizeLimitExceededException(
- format("the request was rejected because its size (%s) exceeds the configured maximum (%s)",
- Long.valueOf(requestSize), Long.valueOf(sizeMax)),
- requestSize, sizeMax);
- }
- // N.B. this is eventually closed in MultipartStream processing
- input = new LimitedInputStream(ctx.getInputStream(), sizeMax) {
- @Override
- protected void raiseError(long pSizeMax, long pCount)
- throws IOException {
- FileUploadException ex = new SizeLimitExceededException(
- format("the request was rejected because its size (%s) exceeds the configured maximum (%s)",
- Long.valueOf(pCount), Long.valueOf(pSizeMax)),
- pCount, pSizeMax);
- throw new FileUploadIOException(ex);
- }
- };
- } else {
- input = ctx.getInputStream();
- }
-
- String charEncoding = fileUploadBase.getHeaderEncoding();
- if (charEncoding == null) {
- charEncoding = ctx.getCharacterEncoding();
- }
-
- multiPartBoundary = fileUploadBase.getBoundary(contentType);
- if (multiPartBoundary == null) {
- IOUtils.closeQuietly(input); // avoid possible resource leak
- throw new FileUploadException("the request was rejected because no multipart boundary was found");
- }
-
- progressNotifier = new MultipartStream.ProgressNotifier(fileUploadBase.getProgressListener(), requestSize);
- try {
- multiPartStream = new MultipartStream(input, multiPartBoundary, progressNotifier);
- } catch (IllegalArgumentException iae) {
- IOUtils.closeQuietly(input); // avoid possible resource leak
- throw new InvalidContentTypeException(
- format("The boundary specified in the %s header is too long", CONTENT_TYPE), iae);
- }
- multiPartStream.setHeaderEncoding(charEncoding);
- }
-
- public MultipartStream getMultiPartStream() throws FileUploadException, IOException {
- if (multiPartStream == null) {
- init(fileUploadBase, ctx);
- }
- return multiPartStream;
- }
-
- /**
- * Called for finding the next item, if any.
- *
- * @return True, if an next item was found, otherwise false.
- * @throws IOException An I/O error occurred.
- */
- private boolean findNextItem() throws FileUploadException, IOException {
- if (eof) {
- return false;
- }
- if (currentItem != null) {
- currentItem.close();
- currentItem = null;
- }
- final MultipartStream multi = getMultiPartStream();
- for (;;) {
- boolean nextPart;
- if (skipPreamble) {
- nextPart = multi.skipPreamble();
- } else {
- nextPart = multi.readBoundary();
- }
- if (!nextPart) {
- if (currentFieldName == null) {
- // Outer multipart terminated -> No more data
- eof = true;
- return false;
- }
- // Inner multipart terminated -> Return to parsing the outer
- multi.setBoundary(multiPartBoundary);
- currentFieldName = null;
- continue;
- }
- FileItemHeaders headers = fileUploadBase.getParsedHeaders(multi.readHeaders());
- if (currentFieldName == null) {
- // We're parsing the outer multipart
- String fieldName = fileUploadBase.getFieldName(headers);
- if (fieldName != null) {
- String subContentType = headers.getHeader(CONTENT_TYPE);
- if (subContentType != null
- && subContentType.toLowerCase(Locale.ENGLISH)
- .startsWith(MULTIPART_MIXED)) {
- currentFieldName = fieldName;
- // Multiple files associated with this field name
- byte[] subBoundary = fileUploadBase.getBoundary(subContentType);
- multi.setBoundary(subBoundary);
- skipPreamble = true;
- continue;
- }
- String fileName = fileUploadBase.getFileName(headers);
- currentItem = new FileItemStreamImpl(this, fileName,
- fieldName, headers.getHeader(CONTENT_TYPE),
- fileName == null, getContentLength(headers));
- currentItem.setHeaders(headers);
- progressNotifier.noteItem();
- itemValid = true;
- return true;
- }
- } else {
- String fileName = fileUploadBase.getFileName(headers);
- if (fileName != null) {
- currentItem = new FileItemStreamImpl(this, fileName,
- currentFieldName,
- headers.getHeader(CONTENT_TYPE),
- false, getContentLength(headers));
- currentItem.setHeaders(headers);
- progressNotifier.noteItem();
- itemValid = true;
- return true;
- }
- }
- multi.discardBodyData();
- }
- }
-
- private long getContentLength(FileItemHeaders pHeaders) {
- try {
- return Long.parseLong(pHeaders.getHeader(CONTENT_LENGTH));
- } catch (Exception e) {
- return -1;
- }
- }
-
- /**
- * Returns, whether another instance of {@link FileItemStream}
- * is available.
- *
- * @throws FileUploadException Parsing or processing the
- * file item failed.
- * @throws IOException Reading the file item failed.
- * @return True, if one or more additional file items
- * are available, otherwise false.
- */
- @Override
- public boolean hasNext() throws FileUploadException, IOException {
- if (eof) {
- return false;
- }
- if (itemValid) {
- return true;
- }
- try {
- return findNextItem();
- } catch (FileUploadIOException e) {
- // unwrap encapsulated SizeException
- throw (FileUploadException) e.getCause();
- }
- }
-
- /**
- * Returns the next available {@link FileItemStream}.
- *
- * @throws java.util.NoSuchElementException No more items are
- * available. Use {@link #hasNext()} to prevent this exception.
- * @throws FileUploadException Parsing or processing the
- * file item failed.
- * @throws IOException Reading the file item failed.
- * @return FileItemStream instance, which provides
- * access to the next file item.
- */
- @Override
- public FileItemStream next() throws FileUploadException, IOException {
- if (eof || (!itemValid && !hasNext())) {
- throw new NoSuchElementException();
- }
- itemValid = false;
- return currentItem;
- }
-
- @Override
- public List<FileItem> getFileItems() throws FileUploadException, IOException {
- final List<FileItem> items = new ArrayList<FileItem>();
- while (hasNext()) {
- final FileItemStream fis = next();
- final FileItem fi = fileUploadBase.getFileItemFactory().createItem(fis.getFieldName(), fis.getContentType(), fis.isFormField(), fis.getName());
- items.add(fi);
- }
- return items;
- }
-
- }
-
- /**
* This exception is thrown for hiding an inner
* {@link FileUploadException} in an {@link IOException}.
*/
diff --git a/src/main/java/org/apache/commons/fileupload2/MultipartStream.java b/src/main/java/org/apache/commons/fileupload2/MultipartStream.java
index 05f344a..ff36d9d 100644
--- a/src/main/java/org/apache/commons/fileupload2/MultipartStream.java
+++ b/src/main/java/org/apache/commons/fileupload2/MultipartStream.java
@@ -116,7 +116,7 @@
* @param pListener The listener to invoke.
* @param pContentLength The expected content length.
*/
- ProgressNotifier(ProgressListener pListener, long pContentLength) {
+ public ProgressNotifier(ProgressListener pListener, long pContentLength) {
listener = pListener;
contentLength = pContentLength;
}
@@ -137,7 +137,7 @@
/**
* Called to indicate, that a new file item has been detected.
*/
- void noteItem() {
+ public void noteItem() {
++items;
notifyListener();
}
@@ -366,7 +366,7 @@
*
* @see #MultipartStream(InputStream, byte[], int, ProgressNotifier)
*/
- MultipartStream(InputStream input,
+ public MultipartStream(InputStream input,
byte[] boundary,
ProgressNotifier pNotifier) {
this(input, boundary, DEFAULT_BUFSIZE, pNotifier);
diff --git a/src/main/java/org/apache/commons/fileupload2/impl/FileItemIteratorImpl.java b/src/main/java/org/apache/commons/fileupload2/impl/FileItemIteratorImpl.java
new file mode 100644
index 0000000..2f0396e
--- /dev/null
+++ b/src/main/java/org/apache/commons/fileupload2/impl/FileItemIteratorImpl.java
@@ -0,0 +1,351 @@
+/*
+ * 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.commons.fileupload2.impl;
+
+import static java.lang.String.format;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.fileupload2.FileItem;
+import org.apache.commons.fileupload2.FileItemHeaders;
+import org.apache.commons.fileupload2.FileItemIterator;
+import org.apache.commons.fileupload2.FileItemStream;
+import org.apache.commons.fileupload2.FileUploadBase;
+import org.apache.commons.fileupload2.FileUploadException;
+import org.apache.commons.fileupload2.MultipartStream;
+import org.apache.commons.fileupload2.ProgressListener;
+import org.apache.commons.fileupload2.RequestContext;
+import org.apache.commons.fileupload2.UploadContext;
+import org.apache.commons.fileupload2.FileUploadBase.FileUploadIOException;
+import org.apache.commons.fileupload2.FileUploadBase.InvalidContentTypeException;
+import org.apache.commons.fileupload2.FileUploadBase.SizeLimitExceededException;
+import org.apache.commons.fileupload2.util.LimitedInputStream;
+import org.apache.commons.io.IOUtils;
+
+/**
+ * The iterator, which is returned by
+ * {@link FileUploadBase#getItemIterator(RequestContext)}.
+ */
+public class FileItemIteratorImpl implements FileItemIterator {
+ private final FileUploadBase fileUploadBase;
+ private final RequestContext ctx;
+ private long sizeMax, fileSizeMax;
+
+
+ @Override
+ public long getSizeMax() {
+ return sizeMax;
+ }
+
+ @Override
+ public void setSizeMax(long sizeMax) {
+ this.sizeMax = sizeMax;
+ }
+
+ @Override
+ public long getFileSizeMax() {
+ return fileSizeMax;
+ }
+
+ @Override
+ public void setFileSizeMax(long fileSizeMax) {
+ this.fileSizeMax = fileSizeMax;
+ }
+
+ /**
+ * The multi part stream to process.
+ */
+ private MultipartStream multiPartStream;
+
+ /**
+ * The notifier, which used for triggering the
+ * {@link ProgressListener}.
+ */
+ private MultipartStream.ProgressNotifier progressNotifier;
+
+ /**
+ * The boundary, which separates the various parts.
+ */
+ private byte[] multiPartBoundary;
+
+ /**
+ * The item, which we currently process.
+ */
+ private FileItemStreamImpl currentItem;
+
+ /**
+ * The current items field name.
+ */
+ private String currentFieldName;
+
+ /**
+ * Whether we are currently skipping the preamble.
+ */
+ private boolean skipPreamble;
+
+ /**
+ * Whether the current item may still be read.
+ */
+ private boolean itemValid;
+
+ /**
+ * Whether we have seen the end of the file.
+ */
+ private boolean eof;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param ctx The request context.
+ * @throws FileUploadException An error occurred while
+ * parsing the request.
+ * @throws IOException An I/O error occurred.
+ */
+ public FileItemIteratorImpl(FileUploadBase pFileUploadBase, RequestContext pRequestContext)
+ throws FileUploadException, IOException {
+ fileUploadBase = pFileUploadBase;
+ sizeMax = fileUploadBase.getSizeMax();
+ fileSizeMax = fileUploadBase.getFileSizeMax();
+ ctx = pRequestContext;
+ if (ctx == null) {
+ throw new NullPointerException("ctx parameter");
+ }
+
+
+ skipPreamble = true;
+ findNextItem();
+ }
+
+ protected void init(FileUploadBase fileUploadBase, RequestContext pRequestContext)
+ throws FileUploadException, IOException {
+ String contentType = ctx.getContentType();
+ if ((null == contentType)
+ || (!contentType.toLowerCase(Locale.ENGLISH).startsWith(FileUploadBase.MULTIPART))) {
+ throw new InvalidContentTypeException(
+ format("the request doesn't contain a %s or %s stream, content type header is %s",
+ FileUploadBase.MULTIPART_FORM_DATA, FileUploadBase.MULTIPART_MIXED, contentType));
+ }
+
+
+ @SuppressWarnings("deprecation") // still has to be backward compatible
+ final int contentLengthInt = ctx.getContentLength();
+
+ final long requestSize = UploadContext.class.isAssignableFrom(ctx.getClass())
+ // Inline conditional is OK here CHECKSTYLE:OFF
+ ? ((UploadContext) ctx).contentLength()
+ : contentLengthInt;
+ // CHECKSTYLE:ON
+
+ InputStream input; // N.B. this is eventually closed in MultipartStream processing
+ if (sizeMax >= 0) {
+ if (requestSize != -1 && requestSize > sizeMax) {
+ throw new SizeLimitExceededException(
+ format("the request was rejected because its size (%s) exceeds the configured maximum (%s)",
+ Long.valueOf(requestSize), Long.valueOf(sizeMax)),
+ requestSize, sizeMax);
+ }
+ // N.B. this is eventually closed in MultipartStream processing
+ input = new LimitedInputStream(ctx.getInputStream(), sizeMax) {
+ @Override
+ protected void raiseError(long pSizeMax, long pCount)
+ throws IOException {
+ FileUploadException ex = new SizeLimitExceededException(
+ format("the request was rejected because its size (%s) exceeds the configured maximum (%s)",
+ Long.valueOf(pCount), Long.valueOf(pSizeMax)),
+ pCount, pSizeMax);
+ throw new FileUploadIOException(ex);
+ }
+ };
+ } else {
+ input = ctx.getInputStream();
+ }
+
+ String charEncoding = fileUploadBase.getHeaderEncoding();
+ if (charEncoding == null) {
+ charEncoding = ctx.getCharacterEncoding();
+ }
+
+ multiPartBoundary = fileUploadBase.getBoundary(contentType);
+ if (multiPartBoundary == null) {
+ IOUtils.closeQuietly(input); // avoid possible resource leak
+ throw new FileUploadException("the request was rejected because no multipart boundary was found");
+ }
+
+ progressNotifier = new MultipartStream.ProgressNotifier(fileUploadBase.getProgressListener(), requestSize);
+ try {
+ multiPartStream = new MultipartStream(input, multiPartBoundary, progressNotifier);
+ } catch (IllegalArgumentException iae) {
+ IOUtils.closeQuietly(input); // avoid possible resource leak
+ throw new InvalidContentTypeException(
+ format("The boundary specified in the %s header is too long", FileUploadBase.CONTENT_TYPE), iae);
+ }
+ multiPartStream.setHeaderEncoding(charEncoding);
+ }
+
+ public MultipartStream getMultiPartStream() throws FileUploadException, IOException {
+ if (multiPartStream == null) {
+ init(fileUploadBase, ctx);
+ }
+ return multiPartStream;
+ }
+
+ /**
+ * Called for finding the next item, if any.
+ *
+ * @return True, if an next item was found, otherwise false.
+ * @throws IOException An I/O error occurred.
+ */
+ private boolean findNextItem() throws FileUploadException, IOException {
+ if (eof) {
+ return false;
+ }
+ if (currentItem != null) {
+ currentItem.close();
+ currentItem = null;
+ }
+ final MultipartStream multi = getMultiPartStream();
+ for (;;) {
+ boolean nextPart;
+ if (skipPreamble) {
+ nextPart = multi.skipPreamble();
+ } else {
+ nextPart = multi.readBoundary();
+ }
+ if (!nextPart) {
+ if (currentFieldName == null) {
+ // Outer multipart terminated -> No more data
+ eof = true;
+ return false;
+ }
+ // Inner multipart terminated -> Return to parsing the outer
+ multi.setBoundary(multiPartBoundary);
+ currentFieldName = null;
+ continue;
+ }
+ FileItemHeaders headers = fileUploadBase.getParsedHeaders(multi.readHeaders());
+ if (currentFieldName == null) {
+ // We're parsing the outer multipart
+ String fieldName = fileUploadBase.getFieldName(headers);
+ if (fieldName != null) {
+ String subContentType = headers.getHeader(FileUploadBase.CONTENT_TYPE);
+ if (subContentType != null
+ && subContentType.toLowerCase(Locale.ENGLISH)
+ .startsWith(FileUploadBase.MULTIPART_MIXED)) {
+ currentFieldName = fieldName;
+ // Multiple files associated with this field name
+ byte[] subBoundary = fileUploadBase.getBoundary(subContentType);
+ multi.setBoundary(subBoundary);
+ skipPreamble = true;
+ continue;
+ }
+ String fileName = fileUploadBase.getFileName(headers);
+ currentItem = new FileItemStreamImpl(this, fileName,
+ fieldName, headers.getHeader(FileUploadBase.CONTENT_TYPE),
+ fileName == null, getContentLength(headers));
+ currentItem.setHeaders(headers);
+ progressNotifier.noteItem();
+ itemValid = true;
+ return true;
+ }
+ } else {
+ String fileName = fileUploadBase.getFileName(headers);
+ if (fileName != null) {
+ currentItem = new FileItemStreamImpl(this, fileName,
+ currentFieldName,
+ headers.getHeader(FileUploadBase.CONTENT_TYPE),
+ false, getContentLength(headers));
+ currentItem.setHeaders(headers);
+ progressNotifier.noteItem();
+ itemValid = true;
+ return true;
+ }
+ }
+ multi.discardBodyData();
+ }
+ }
+
+ private long getContentLength(FileItemHeaders pHeaders) {
+ try {
+ return Long.parseLong(pHeaders.getHeader(FileUploadBase.CONTENT_LENGTH));
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+
+ /**
+ * Returns, whether another instance of {@link FileItemStream}
+ * is available.
+ *
+ * @throws FileUploadException Parsing or processing the
+ * file item failed.
+ * @throws IOException Reading the file item failed.
+ * @return True, if one or more additional file items
+ * are available, otherwise false.
+ */
+ @Override
+ public boolean hasNext() throws FileUploadException, IOException {
+ if (eof) {
+ return false;
+ }
+ if (itemValid) {
+ return true;
+ }
+ try {
+ return findNextItem();
+ } catch (FileUploadIOException e) {
+ // unwrap encapsulated SizeException
+ throw (FileUploadException) e.getCause();
+ }
+ }
+
+ /**
+ * Returns the next available {@link FileItemStream}.
+ *
+ * @throws java.util.NoSuchElementException No more items are
+ * available. Use {@link #hasNext()} to prevent this exception.
+ * @throws FileUploadException Parsing or processing the
+ * file item failed.
+ * @throws IOException Reading the file item failed.
+ * @return FileItemStream instance, which provides
+ * access to the next file item.
+ */
+ @Override
+ public FileItemStream next() throws FileUploadException, IOException {
+ if (eof || (!itemValid && !hasNext())) {
+ throw new NoSuchElementException();
+ }
+ itemValid = false;
+ return currentItem;
+ }
+
+ @Override
+ public List<FileItem> getFileItems() throws FileUploadException, IOException {
+ final List<FileItem> items = new ArrayList<FileItem>();
+ while (hasNext()) {
+ final FileItemStream fis = next();
+ final FileItem fi = fileUploadBase.getFileItemFactory().createItem(fis.getFieldName(), fis.getContentType(), fis.isFormField(), fis.getName());
+ items.add(fi);
+ }
+ return items;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/commons/fileupload2/impl/FileItemStreamImpl.java b/src/main/java/org/apache/commons/fileupload2/impl/FileItemStreamImpl.java
index be48435..9a40a25 100644
--- a/src/main/java/org/apache/commons/fileupload2/impl/FileItemStreamImpl.java
+++ b/src/main/java/org/apache/commons/fileupload2/impl/FileItemStreamImpl.java
@@ -26,8 +26,6 @@
import org.apache.commons.fileupload2.FileUploadBase;
import org.apache.commons.fileupload2.FileUploadException;
import org.apache.commons.fileupload2.InvalidFileNameException;
-import org.apache.commons.fileupload2.MultipartStream;
-import org.apache.commons.fileupload2.FileItemStream.ItemSkippedException;
import org.apache.commons.fileupload2.FileUploadBase.FileSizeLimitExceededException;
import org.apache.commons.fileupload2.FileUploadBase.FileUploadIOException;
import org.apache.commons.fileupload2.MultipartStream.ItemInputStream;
@@ -40,7 +38,7 @@
* Default implementation of {@link FileItemStream}.
*/
public class FileItemStreamImpl implements FileItemStream {
- private final FileUploadBase.FileItemIteratorImpl fileItemIteratorImpl;
+ private final FileItemIteratorImpl fileItemIteratorImpl;
/**
* The file items content type.
@@ -87,7 +85,7 @@
* @param pContentLength The items content length, if known, or -1
* @throws IOException Creating the file item failed.
*/
- public FileItemStreamImpl(FileUploadBase.FileItemIteratorImpl pFileItemIterator, String pName, String pFieldName,
+ public FileItemStreamImpl(FileItemIteratorImpl pFileItemIterator, String pName, String pFieldName,
String pContentType, boolean pFormField,
long pContentLength) throws FileUploadException, IOException {
fileItemIteratorImpl = pFileItemIterator;
diff --git a/src/test/java/org/apache/commons/fileupload2/StreamingTest.java b/src/test/java/org/apache/commons/fileupload2/StreamingTest.java
index 0fb11f5..b80bee0 100644
--- a/src/test/java/org/apache/commons/fileupload2/StreamingTest.java
+++ b/src/test/java/org/apache/commons/fileupload2/StreamingTest.java
@@ -267,10 +267,8 @@
assertTrue(e.getMessage().indexOf("foo.exe\\0.png") != -1);
}
- List<FileItem> fileItems = parseUpload(reqBytes);
- final FileItem fileItem = fileItems.get(0);
try {
- fileItem.getName();
+ List<FileItem> fileItems = parseUpload(reqBytes);
fail("Expected exception");
} catch (InvalidFileNameException e) {
assertEquals(fileName, e.getName());