use of com.palantir.conjure.java.undertow.processor.data.ReturnType in project conjure-java by palantir.
the class ConjureUndertowEndpointsGenerator method endpoint.
// TODO(ckozak): refactor
@SuppressWarnings("checkstyle:MethodLength")
private static TypeSpec endpoint(ServiceDefinition service, EndpointDefinition endpoint) {
List<AdditionalField> additionalFields = new ArrayList<>();
MethodSpec.Builder handlerBuilder = MethodSpec.methodBuilder("handleRequest").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).addParameter(HttpServerExchange.class, EXCHANGE_NAME).addException(Exception.class);
ReturnType returnType = endpoint.returns();
TypeName responseTypeName = returnType.asyncInnerType().orElseGet(returnType::returnType).box();
if (usesRequestContext(endpoint)) {
handlerBuilder.addStatement("$T $N = this.$N.contexts().createContext($N, this)", RequestContext.class, REQUEST_CONTEXT, RUNTIME_NAME, EXCHANGE_NAME);
}
endpoint.arguments().forEach(def -> def.paramType().match(new Cases<Void>() {
@Override
public Void body(CodeBlock deserializerFactory, String deserializerFieldName) {
TypeName requestBodyType = def.argType().match(ArgTypeTypeName.INSTANCE).box();
additionalFields.add(ImmutableAdditionalField.builder().field(FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(Deserializer.class), requestBodyType), deserializerFieldName, Modifier.PRIVATE, Modifier.FINAL).build()).constructorInitializer(CodeBlock.builder().addStatement("this.$N = $L.deserializer(new $T<$T>() {}, $N, this)", deserializerFieldName, deserializerFactory, TypeMarker.class, requestBodyType, RUNTIME_NAME).build()).build());
return null;
}
@Override
public Void header(String variableName, String headerName, String deserializerFieldName, CodeBlock deserializerFactory, SafeLoggingAnnotation safeLoggable) {
TypeName paramType = def.argType().match(ArgTypeTypeName.INSTANCE);
additionalFields.add(ImmutableAdditionalField.builder().field(FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(Deserializer.class), paramType.box()), deserializerFieldName, Modifier.PRIVATE, Modifier.FINAL).build()).constructorInitializer(CodeBlock.builder().addStatement("this.$N = new $T<>($S, $L)", deserializerFieldName, HeaderParamDeserializer.class, headerName, deserializerFactory).build()).build());
handlerBuilder.addStatement("$T $N = $L", paramType, variableName, invokeDeserializer(def));
getSafeLogging(headerName, variableName, safeLoggable).ifPresent(handlerBuilder::addStatement);
return null;
}
@Override
public Void path(String paramName, String deserializerFieldName, CodeBlock deserializerFactory, SafeLoggingAnnotation safeLoggable) {
TypeName paramType = def.argType().match(ArgTypeTypeName.INSTANCE);
additionalFields.add(ImmutableAdditionalField.builder().field(FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(Deserializer.class), paramType.box()), deserializerFieldName, Modifier.PRIVATE, Modifier.FINAL).build()).constructorInitializer(CodeBlock.builder().addStatement("this.$N = new $T<>($S, $L)", deserializerFieldName, PathParamDeserializer.class, paramName, deserializerFactory).build()).build());
handlerBuilder.addStatement("$T $N = $L", paramType, paramName, invokeDeserializer(def));
getSafeLogging(paramName, paramName, safeLoggable).ifPresent(handlerBuilder::addStatement);
return null;
}
@Override
public Void pathMulti(String paramName, String deserializerFieldName, CodeBlock deserializerFactory, SafeLoggingAnnotation safeLoggable) {
TypeName paramType = def.argType().match(ArgTypeTypeName.INSTANCE);
additionalFields.add(ImmutableAdditionalField.builder().field(FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(Deserializer.class), paramType.box()), deserializerFieldName, Modifier.PRIVATE, Modifier.FINAL).build()).constructorInitializer(CodeBlock.builder().addStatement("this.$N = new $T<>($S, $L)", deserializerFieldName, PathMultiParamDeserializer.class, "*", deserializerFactory).build()).build());
handlerBuilder.addStatement("$T $N = $L", paramType, paramName, invokeDeserializer(def));
getSafeLogging(paramName, paramName, safeLoggable).ifPresent(handlerBuilder::addStatement);
return null;
}
@Override
public Void query(String variableName, String paramName, String deserializerFieldName, CodeBlock deserializerFactory, SafeLoggingAnnotation safeLoggable) {
TypeName paramType = def.argType().match(ArgTypeTypeName.INSTANCE);
additionalFields.add(ImmutableAdditionalField.builder().field(FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(Deserializer.class), paramType.box()), deserializerFieldName, Modifier.PRIVATE, Modifier.FINAL).build()).constructorInitializer(CodeBlock.builder().addStatement("this.$N = new $T<>($S, $L)", deserializerFieldName, QueryParamDeserializer.class, paramName, deserializerFactory).build()).build());
handlerBuilder.addStatement("$T $N = $L", paramType, variableName, invokeDeserializer(def));
getSafeLogging(paramName, variableName, safeLoggable).ifPresent(handlerBuilder::addStatement);
return null;
}
@Override
public Void cookie(String variableName, String cookieName, String deserializerFieldName, CodeBlock deserializerFactory, SafeLoggingAnnotation safeLoggable) {
TypeName paramType = def.argType().match(ArgTypeTypeName.INSTANCE);
additionalFields.add(ImmutableAdditionalField.builder().field(FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(Deserializer.class), paramType.box()), deserializerFieldName, Modifier.PRIVATE, Modifier.FINAL).build()).constructorInitializer(CodeBlock.builder().addStatement("this.$N = new $T<>($S, $L)", deserializerFieldName, CookieDeserializer.class, cookieName, deserializerFactory).build()).build());
handlerBuilder.addStatement("$T $N = $L", paramType, variableName, invokeDeserializer(def));
getSafeLogging(cookieName, variableName, safeLoggable).ifPresent(handlerBuilder::addStatement);
return null;
}
@Override
public Void authCookie(String variableName, String cookieName, String deserializerFieldName) {
TypeName paramType = def.argType().match(ArgTypeTypeName.INSTANCE);
additionalFields.add(ImmutableAdditionalField.builder().field(FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(Deserializer.class), paramType.box()), deserializerFieldName, Modifier.PRIVATE, Modifier.FINAL).build()).constructorInitializer(CodeBlock.builder().addStatement("this.$N = new $T(runtime, $S)", deserializerFieldName, BearerTokenCookieDeserializer.class, cookieName).build()).build());
handlerBuilder.addStatement("$T $N = $L", paramType, variableName, invokeDeserializer(def));
return null;
}
@Override
public Void authHeader(String variableName) {
handlerBuilder.addStatement("$T $N = $L", AuthHeader.class, variableName, invokeDeserializer(def));
return null;
}
@Override
public Void exchange() {
return null;
}
@Override
public Void context() {
return null;
}
}));
if (returnType.asyncInnerType().isEmpty() && returnType.isVoid()) {
handlerBuilder.addStatement(invokeDelegate(endpoint)).addStatement("$N.setStatusCode($T.NO_CONTENT)", EXCHANGE_NAME, StatusCodes.class);
} else {
additionalFields.add(ImmutableAdditionalField.builder().field(FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(Serializer.class), responseTypeName), returnType.serializerFieldName(), Modifier.PRIVATE, Modifier.FINAL).build()).constructorInitializer(CodeBlock.builder().addStatement("this.$N = $L.serializer(new $T<$T>() {}, $N, this)", returnType.serializerFieldName(), returnType.serializerFactory(), TypeMarker.class, responseTypeName, RUNTIME_NAME).build()).build());
if (returnType.asyncInnerType().isPresent()) {
handlerBuilder.addStatement("$N.async().register($L, this, $N)", RUNTIME_NAME, invokeDelegate(endpoint), EXCHANGE_NAME);
} else {
handlerBuilder.addStatement("write($L, $N)", invokeDelegate(endpoint), EXCHANGE_NAME);
}
}
TypeSpec.Builder endpointBuilder = TypeSpec.classBuilder(endpointClassName(endpoint.endpointName())).addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL).addSuperinterface(HttpHandler.class).addSuperinterface(Endpoint.class).addField(UndertowRuntime.class, RUNTIME_NAME, Modifier.PRIVATE, Modifier.FINAL).addField(service.serviceInterface(), DELEGATE_NAME, Modifier.PRIVATE, Modifier.FINAL).addFields(additionalFields.stream().map(AdditionalField::field).collect(ImmutableList.toImmutableList())).addMethod(MethodSpec.constructorBuilder().addParameter(UndertowRuntime.class, RUNTIME_NAME).addParameter(service.serviceInterface(), DELEGATE_NAME).addStatement("this.$1N = $1N", RUNTIME_NAME).addStatement("this.$1N = $1N", DELEGATE_NAME).addCode(additionalFields.stream().map(AdditionalField::constructorInitializer).collect(CodeBlock.joining(""))).build()).addMethod(handlerBuilder.build());
if (!TypeName.VOID.equals(returnType.returnType())) {
endpointBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(ReturnValueWriter.class), responseTypeName));
endpointBuilder.addMethod(MethodSpec.methodBuilder("write").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).addParameter(responseTypeName, RETURN_VALUE).addParameter(HttpServerExchange.class, EXCHANGE_NAME).addException(IOException.class).addStatement("this.$N.serialize($N, $N)", returnType.serializerFieldName(), RETURN_VALUE, EXCHANGE_NAME).build());
}
return endpointBuilder.addMethod(MethodSpec.methodBuilder("method").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).returns(HttpString.class).addStatement("return $T.$N", Methods.class, endpoint.httpMethod().name()).build()).addMethod(MethodSpec.methodBuilder("template").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).returns(String.class).addStatement("return $S", endpoint.httpPath().path()).build()).addMethod(MethodSpec.methodBuilder("serviceName").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).returns(String.class).addStatement("return $S", endpoint.serviceName().get()).build()).addMethod(MethodSpec.methodBuilder("name").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).returns(String.class).addStatement("return $S", endpoint.endpointName().get()).build()).addMethod(MethodSpec.methodBuilder("handler").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).returns(HttpHandler.class).addStatement("return this").build()).build();
}
Aggregations