@Override public CompletionStage<? extends T> apply(Flow.Publisher<DataChunk> publisher, Class<? super T> clazz) { return reader.apply(publisher, clazz); } }
/** * Transforms a publisher into a completion stage. * If an exception is thrown, the resulting completion stage of * {@link Content#as(Class)} method call ends exceptionally. * <p> * The default implementation calls {@link #apply(Flow.Publisher, Class)} with {@link Object} as * the class parameter. * * @param publisher the publisher to transform * @return the result as a completion stage */ default CompletionStage<? extends R> apply(Flow.Publisher<DataChunk> publisher) { return apply(publisher, Object.class); }
/** * Transforms a publisher into a completion stage. * If an exception is thrown, the resulting completion stage of * {@link Content#as(Class)} method call ends exceptionally. * <p> * The default implementation calls {@link #apply(Flow.Publisher, Class)} with {@link Object} as * the class parameter. * * @param publisher the publisher to transform * @param type the desired type to cast the guarantied {@code R} type to * @param <T> the desired type to cast the guarantied {@code R} type to * @return the result as a completion stage which might end exceptionally with * {@link ClassCastException} if the {@code R} type wasn't possible to cast * to {@code T} */ default <T extends R> CompletionStage<? extends T> applyAndCast(Flow.Publisher<DataChunk> publisher, Class<T> type) { // if this was implemented as (CompletionStage<? extends T>) apply(publisher, (Class<R>) clazz); // the class cast exception might occur outside of the completion stage which might be confusing return apply(publisher, (Class<R>) type).thenApply(type::cast); } }
/** * Converts a {@link ByteBuffer} publisher to a single string while using the associated * charset. If the charset cannot be used by the JVM, the returned completion stage ends * exceptionally with an {@link IllegalArgumentException}. * * @param publisher the publisher from which to transform the byte chunks into a single * string * @return a completion stage representing the to be created string; if the associated * charset cannot be used by this JVM, it ends exceptionally with an * {@link IllegalArgumentException} */ @Override public CompletionStage<String> apply(Flow.Publisher<DataChunk> publisher, Class<? super String> clazz) { if (charset != null) { return ContentReaders .byteArrayReader() .apply(publisher, byte[].class) .thenApply(bytes -> new String(bytes, charset)); } CompletableFuture<String> result = new CompletableFuture<>(); result.completeExceptionally(new IllegalArgumentException( "Cannot produce a string with the expected charset.", e)); return result; }
@Override @SuppressWarnings("unchecked") public <T> CompletionStage<T> as(Class<T> type) { Span readSpan = createReadSpan(type); CompletionStage<T> result; try { readersLock.readLock().lock(); result = readersWithDefaults() .filter(reader -> reader.accept(type)) .findFirst() // in this context, the cast is absurd, although it's needed; // one can create a predicate matching an incompatible class .map(reader -> (CompletionStage<? extends T>) (((Reader<T>) reader).apply(chainPublishers(), type))) .orElse(failedFuture(new IllegalArgumentException("No reader found for class: " + type))); } catch (Exception e) { result = failedFuture(new IllegalArgumentException("Transformation failed!", e)); } finally { readersLock.readLock().unlock(); } // Close span result.thenRun(readSpan::finish) .exceptionally(t -> { finishSpanWithError(readSpan, t); return null; }); return result; }
/** * Returns a function (reader) converting {@link Flow.Publisher Publisher} of {@link java.nio.ByteBuffer}s to * a JSON-P object. * <p> * It is intended for derivation of others, more specific readers. * * @param charset a charset to use charset * @return the byte array content reader that transforms a publisher of byte buffers to a completion stage that * might end exceptionally with a {@link IllegalArgumentException} in case of I/O error or * a {@link javax.json.JsonException} */ public Reader<JsonStructure> reader(Charset charset) { return (publisher, clazz) -> ContentReaders.byteArrayReader() .apply(publisher) .thenApply(bytes -> jsonReaderFactory.createReader(new ByteArrayInputStream(bytes), charset).read()); }
.registerReader(JsonStructure.class::isAssignableFrom, (publisher, type) -> { Charset charset = determineCharset(request.headers()); return reader(charset).apply(publisher); });
/** * Converts a {@link ByteBuffer} publisher to a single string while using the associated * charset. If the charset cannot be used by the JVM, the returned completion stage ends * exceptionally with an {@link IllegalArgumentException}. * * @param publisher the publisher from which to transform the byte chunks into a single * string * @return a completion stage representing the to be created string; if the associated * charset cannot be used by this JVM, it ends exceptionally with an * {@link IllegalArgumentException} */ @Override public CompletionStage<String> apply(Flow.Publisher<DataChunk> publisher, Class<? super String> clazz) { if (charset != null) { return ContentReaders .byteArrayReader() .apply(publisher, byte[].class) .thenApply(bytes -> new String(bytes, charset)); } CompletableFuture<String> result = new CompletableFuture<>(); result.completeExceptionally(new IllegalArgumentException( "Cannot produce a string with the expected charset.", e)); return result; }
/** * Returns a function (reader) converting {@link Flow.Publisher Publisher} of {@link java.nio.ByteBuffer}s to * a JSON-P object. * <p> * It is intended for derivation of others, more specific readers. * * @param charset a charset to use charset * @return the byte array content reader that transforms a publisher of byte buffers to a completion stage that * might end exceptionally with a {@link IllegalArgumentException} in case of I/O error or * a {@link javax.json.JsonException} */ public Reader<JsonStructure> reader(Charset charset) { return (publisher, clazz) -> ContentReaders.byteArrayReader() .apply(publisher) .thenApply(bytes -> jsonReaderFactory.createReader(new ByteArrayInputStream(bytes), charset).read()); }
.registerReader(JsonStructure.class::isAssignableFrom, (publisher, type) -> { Charset charset = determineCharset(request.headers()); return reader(charset).apply(publisher); });