diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/content/ContentSourceCompletableFuture.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/content/ContentSourceCompletableFuture.java index ff0ef9dc7e33..f44d92832618 100644 --- a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/content/ContentSourceCompletableFuture.java +++ b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/content/ContentSourceCompletableFuture.java @@ -19,31 +19,36 @@ import org.eclipse.jetty.io.Content; /** - * A utility class to convert content from a {@link Content.Source} to an instance - * available via a {@link CompletableFuture}. - *

- * An example usage to asynchronously read UTF-8 content is: - *

+ *

A utility class to convert content from a {@link Content.Source} to an instance + * available via a {@link CompletableFuture}.

+ *

An example usage to asynchronously read UTF-8 content is:

*
{@code
- *     public static class FutureUtf8String extends ContentSourceCompletableFuture;
+ * public static class CompletableUTF8String extends ContentSourceCompletableFuture;
+ * {
+ *     private final Utf8StringBuilder builder = new Utf8StringBuilder();
+ *
+ *     public CompletableUTF8String(Content.Source content)
+ *     {
+ *         super(content);
+ *     }
+ *
+ *     @Override
+ *     protected String parse(Content.Chunk chunk) throws Throwable
  *     {
- *         Utf8StringBuilder builder = new Utf8StringBuilder();
+ *         // Accumulate the chunk bytes.
+ *         if (chunk.hasRemaining())
+ *             builder.append(chunk.getByteBuffer());
  *
- *         public FutureUtf8String(Content.Source content)
- *         {
- *             super(content);
- *         }
+ *         // Not the last chunk, the result is not ready yet.
+ *         if (!chunk.isLast())
+ *             return null;
  *
- *         @Override
- *         protected String parse(Content.Chunk chunk) throws Throwable
- *         {
- *             if (chunk.hasRemaining())
- *                 builder.append(chunk.getByteBuffer());
- *             return chunk.isLast() ? builder.takeCompleteString(IllegalStateException::new) : null;
- *         }
+ *         // The result is ready.
+ *         return builder.takeCompleteString(IllegalStateException::new);
  *     }
- *     ...
- *     new FutureUtf8String(source).thenAccept(System.err::println);
+ * }
+ * 
+ * new CompletableUTF8String(source).thenAccept(System.err::println);
  * }
*/ public abstract class ContentSourceCompletableFuture extends CompletableFuture @@ -56,12 +61,15 @@ public ContentSourceCompletableFuture(Content.Source content) } /** - * Progress the parsing, {@link Content.Source#read() reading} and/or {@link Content.Source#demand(Runnable) demanding} - * as necessary. - *

- * This method must be called once to initiate the reading and parsing, - * and is then called to progress parsing in response to any {@link Content.Source#demand(Runnable) demand} calls. - *

+ *

Initiates the parsing of the {@link Content.Source}.

+ *

For every valid chunk that is read, {@link #parse(Content.Chunk)} + * is called, until a result is produced that is used to + * complete this {@link CompletableFuture}.

+ *

Internally, this method is called multiple times to progress + * the parsing in response to {@link Content.Source#demand(Runnable)} + * calls.

+ *

Exceptions thrown during parsing result in this + * {@link CompletableFuture} to be completed exceptionally.

*/ public void parse() { @@ -109,21 +117,24 @@ public void parse() } /** - * Called to parse a {@link org.eclipse.jetty.io.Content.Chunk} - * @param chunk The chunk containing content to parse. The chunk will never be null nor a + *

Called by {@link #parse()} to parse a {@link org.eclipse.jetty.io.Content.Chunk}.

+ * + * @param chunk The chunk containing content to parse. The chunk will never be {@code null} nor a * {@link org.eclipse.jetty.io.Content.Chunk#isFailure(Content.Chunk) failure chunk}. - * If references to the content of the chunk are to be held beyond the scope of this call, - * then implementations must call {@link Content.Chunk#retain()} and {@link Content.Chunk#release()} - * as appropriate. - * @return The parsed {@code X} instance or null if parsing is not yet complete - * @throws Throwable Thrown if there is an error parsing + * If the chunk is stored away to be used later beyond the scope of this call, + * then implementations must call {@link Content.Chunk#retain()} and + * {@link Content.Chunk#release()} as appropriate. + * @return The parsed {@code X} result instance or {@code null} if parsing is not yet complete + * @throws Throwable If there is an error parsing */ protected abstract X parse(Content.Chunk chunk) throws Throwable; /** - * @param cause A {@link Content.Chunk#isLast() non-last} + *

Callback method that informs the parsing about how to handle transient failures.

+ * + * @param cause A transient failure obtained by reading a {@link Content.Chunk#isLast() non-last} * {@link org.eclipse.jetty.io.Content.Chunk#isFailure(Content.Chunk) failure chunk} - * @return True if the chunk can be ignored. + * @return {@code true} if the transient failure can be ignored, {@code false} otherwise */ protected boolean onTransientFailure(Throwable cause) {