Skip to content

Commit

Permalink
Merge pull request #14748 from geoand/#14720
Browse files Browse the repository at this point in the history
Ensure that ServerStringMessageBodyHandler doesn't affect build time resolution of builders
  • Loading branch information
gsmet authored Feb 2, 2021
2 parents 38acffd + 2321d0c commit 483d142
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.quarkus.resteasy.reactive.jackson.runtime.serialisers;

import static org.jboss.resteasy.reactive.server.vertx.providers.serialisers.json.JsonMessageBodyWriterUtil.*;
import static org.jboss.resteasy.reactive.server.vertx.providers.serialisers.json.JsonMessageBodyWriterUtil.setContentTypeIfNecessary;

import java.io.IOException;
import java.io.OutputStream;
Expand Down Expand Up @@ -30,7 +30,7 @@

import io.quarkus.resteasy.reactive.jackson.CustomSerialization;

public class JacksonMessageBodyWriter implements ServerMessageBodyWriter<Object> {
public class JacksonMessageBodyWriter extends ServerMessageBodyWriter.AllWriteableMessageBodyWriter {

private static final String JSON_VIEW_NAME = JsonView.class.getName();
private static final String CUSTOM_SERIALIZATION = CustomSerialization.class.getName();
Expand Down Expand Up @@ -62,11 +62,6 @@ private static void setNecessaryJsonFactoryConfig(JsonFactory jsonFactory) {
jsonFactory.configure(Feature.FLUSH_PASSED_TO_STREAM, false);
}

@Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return true;
}

@Override
public void writeTo(Object o, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
Expand All @@ -87,11 +82,6 @@ public void writeTo(Object o, Class<?> type, Type genericType, Annotation[] anno
}
}

@Override
public boolean isWriteable(Class<?> type, Type genericType, ResteasyReactiveResourceInfo target, MediaType mediaType) {
return true;
}

@Override
public void writeResponse(Object o, Type genericType, ServerRequestContext context)
throws WebApplicationException, IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;

import org.jboss.resteasy.reactive.server.spi.ResteasyReactiveResourceInfo;
import org.jboss.resteasy.reactive.server.spi.ServerMessageBodyWriter;
import org.jboss.resteasy.reactive.server.spi.ServerRequestContext;

public class JsonbMessageBodyWriter implements ServerMessageBodyWriter<Object> {
public class JsonbMessageBodyWriter extends ServerMessageBodyWriter.AllWriteableMessageBodyWriter {

private final Jsonb json;

Expand All @@ -26,11 +25,6 @@ public JsonbMessageBodyWriter(Jsonb json) {
this.json = json;
}

@Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return true;
}

@Override
public void writeTo(Object o, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
Expand All @@ -42,11 +36,6 @@ public void writeTo(Object o, Class<?> type, Type genericType, Annotation[] anno
}
}

@Override
public boolean isWriteable(Class<?> type, Type genericType, ResteasyReactiveResourceInfo target, MediaType mediaType) {
return true;
}

@Override
public void writeResponse(Object o, Type genericType, ServerRequestContext context)
throws WebApplicationException, IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,7 @@ public RuntimeResource buildResourceMethod(ResourceClass clazz,
+ "#" + method.getName() + "(" + Arrays.toString(method.getParameters()) + ")");
handlers.add(new VariableProducesHandler(serverMediaType, serialisers));
score.add(ScoreSystem.Category.Writer, ScoreSystem.Diagnostic.WriterRunTime);
} else if (buildTimeWriters.size() == 1) {
//only a single handler that can handle the response
//this is a very common case
} else if (isSingleEffectiveWriter(buildTimeWriters)) {
MessageBodyWriter<?> writer = buildTimeWriters.get(0);
handlers.add(new FixedProducesHandler(mediaType, new FixedEntityWriter(
writer, serialisers)));
Expand Down Expand Up @@ -364,6 +362,16 @@ public RuntimeResource buildResourceMethod(ResourceClass clazz,
pathParameterIndexes, score, sseElementType, clazz.resourceExceptionMapper());
}

private boolean isSingleEffectiveWriter(List<MessageBodyWriter<?>> buildTimeWriters) {
if (buildTimeWriters.size() == 1) { // common case of single writer
return true;
}

// in the case where the first Writer is an instance of AllWriteableMessageBodyWriter,
// it doesn't matter that we have multiple writers as the first one will always be used to serialize
return buildTimeWriters.get(0) instanceof ServerMessageBodyWriter.AllWriteableMessageBodyWriter;
}

private void addHandlers(List<ServerRestHandler> handlers, ServerResourceMethod method, DeploymentInfo info,
HandlerChainCustomizer.Phase phase) {
for (int i = 0; i < info.getGlobalHandlerCustomizers().size(); i++) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.jboss.resteasy.reactive.server.spi;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
Expand All @@ -15,4 +16,24 @@ public interface ServerMessageBodyWriter<T> extends MessageBodyWriter<T> {

void writeResponse(T o, Type genericType, ServerRequestContext context) throws WebApplicationException, IOException;

/**
* A special super-class of MessageBodyWriters that accepts all types of input.
* The main purpose of this class is to allow runtime code
* to optimize for the case when there are multiple providers determined at build time
* but the first one will always be used
*/
abstract class AllWriteableMessageBodyWriter implements ServerMessageBodyWriter<Object> {

@Override
public final boolean isWriteable(Class<?> type, Type genericType, ResteasyReactiveResourceInfo target,
MediaType mediaType) {
return true;
}

@Override
public final boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return true;
}
}
}

0 comments on commit 483d142

Please sign in to comment.