Skip to content

Commit

Permalink
Route annotations with the same values share a single handler instance
Browse files Browse the repository at this point in the history
- resolves quarkusio#10597
  • Loading branch information
mkouba committed Jul 16, 2020
1 parent d05217d commit 436c63b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,34 @@
import org.jboss.jandex.MethodInfo;
import org.jboss.jandex.Type;

import io.vertx.core.buffer.Buffer;

/**
* Describe a request handler.
*/
public class HandlerDescriptor {
class HandlerDescriptor {

private final MethodInfo method;

public HandlerDescriptor(MethodInfo method) {
HandlerDescriptor(MethodInfo method) {
this.method = method;
}

public Type getReturnType() {
Type getReturnType() {
return method.returnType();
}

public boolean isReturningVoid() {
boolean isReturningVoid() {
return method.returnType().kind().equals(Type.Kind.VOID);
}

public boolean isReturningUni() {
boolean isReturningUni() {
return method.returnType().name().equals(DotNames.UNI);
}

public boolean isReturningMulti() {
boolean isReturningMulti() {
return method.returnType().name().equals(DotNames.MULTI);
}

public Type getContentType() {
Type getContentType() {
if (isReturningVoid()) {
return null;
}
Expand All @@ -46,23 +44,23 @@ public Type getContentType() {
return getReturnType();
}

public boolean isContentTypeString() {
boolean isContentTypeString() {
Type type = getContentType();
if (type == null) {
return false;
}
return type.name().equals(io.quarkus.arc.processor.DotNames.STRING);
}

public boolean isContentTypeBuffer() {
boolean isContentTypeBuffer() {
Type type = getContentType();
if (type == null) {
return false;
}
return type.name().equals(DotNames.BUFFER);
}

public boolean isContentTypeRxBuffer() {
boolean isContentTypeRxBuffer() {
Type type = getContentType();
if (type == null) {
return false;
Expand All @@ -71,7 +69,7 @@ public boolean isContentTypeRxBuffer() {
.equals(DotName.createSimple(io.vertx.reactivex.core.buffer.Buffer.class.getName()));
}

public boolean isContentTypeMutinyBuffer() {
boolean isContentTypeMutinyBuffer() {
Type type = getContentType();
if (type == null) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,6 @@ void addAdditionalRoutes(
Map<RouteMatcher, MethodInfo> matchers = new HashMap<>();

for (AnnotatedRouteHandlerBuildItem businessMethod : routeHandlerBusinessMethods) {
String handlerClass = generateHandler(new HandlerDescriptor(businessMethod.getMethod()),
businessMethod.getBean(), businessMethod.getMethod(), classOutput, transformedAnnotations);
reflectiveClasses.produce(new ReflectiveClassBuildItem(false, false, handlerClass));
Handler<RoutingContext> routingHandler = recorder.createHandler(handlerClass);

AnnotationInstance routeBaseAnnotation = businessMethod.getRouteBase();
String pathPrefix = null;
String[] baseProduces = null;
Expand All @@ -227,7 +222,22 @@ void addAdditionalRoutes(
}
}

// Route annotations with the same values share a single handler instance
// @Route string value -> handler
Map<String, Handler<RoutingContext>> routeHandlers = new HashMap<>();

for (AnnotationInstance route : businessMethod.getRoutes()) {
String routeString = route.toString(true);
Handler<RoutingContext> routeHandler = routeHandlers.get(routeString);
if (routeHandler == null) {
String handlerClass = generateHandler(new HandlerDescriptor(businessMethod.getMethod()),
businessMethod.getBean(), businessMethod.getMethod(), classOutput, transformedAnnotations,
routeString);
reflectiveClasses.produce(new ReflectiveClassBuildItem(false, false, handlerClass));
routeHandler = recorder.createHandler(handlerClass);
routeHandlers.put(routeString, routeHandler);
}

AnnotationValue regexValue = route.value(VALUE_REGEX);
AnnotationValue pathValue = route.value(VALUE_PATH);
AnnotationValue orderValue = route.valueWithDefault(index, VALUE_ORDER);
Expand Down Expand Up @@ -296,13 +306,14 @@ void addAdditionalRoutes(
throw new IllegalStateException("Unkown type " + typeString);
}
}
routeProducer.produce(new RouteBuildItem(routeFunction, routingHandler, handlerType));
routeProducer.produce(new RouteBuildItem(routeFunction, routeHandler, handlerType));
}
}

for (AnnotatedRouteFilterBuildItem filterMethod : routeFilterBusinessMethods) {
String handlerClass = generateHandler(new HandlerDescriptor(filterMethod.getMethod()),
filterMethod.getBean(), filterMethod.getMethod(), classOutput, transformedAnnotations);
filterMethod.getBean(), filterMethod.getMethod(), classOutput, transformedAnnotations,
filterMethod.getRouteFilter().toString(true));
reflectiveClasses.produce(new ReflectiveClassBuildItem(false, false, handlerClass));
Handler<RoutingContext> routingHandler = recorder.createHandler(handlerClass);
AnnotationValue priorityValue = filterMethod.getRouteFilter().value();
Expand Down Expand Up @@ -393,7 +404,7 @@ private void validateRouteMethod(BeanInfo bean, MethodInfo method, TransformedAn
}

private String generateHandler(HandlerDescriptor desc, BeanInfo bean, MethodInfo method, ClassOutput classOutput,
TransformedAnnotationsBuildItem transformedAnnotations) {
TransformedAnnotationsBuildItem transformedAnnotations, String hashSuffix) {

String baseName;
if (bean.getImplClazz().enclosingClass() != null) {
Expand All @@ -410,7 +421,7 @@ private String generateHandler(HandlerDescriptor desc, BeanInfo bean, MethodInfo
sigBuilder.append(i.name().toString());
}
String generatedName = targetPackage.replace('.', '/') + "/" + baseName + HANDLER_SUFFIX + "_" + method.name() + "_"
+ HashUtil.sha1(sigBuilder.toString());
+ HashUtil.sha1(sigBuilder.toString() + hashSuffix);

ClassCreator invokerCreator = ClassCreator.builder().classOutput(classOutput).className(generatedName)
.interfaces(RouteHandler.class).build();
Expand Down

0 comments on commit 436c63b

Please sign in to comment.