use of com.palantir.conjure.spec.Type in project conjure-java by palantir.
the class UndertowServiceHandlerGenerator method generateEndpointHandler.
private TypeSpec generateEndpointHandler(EndpointDefinition endpointDefinition, ServiceDefinition serviceDefinition, ClassName serviceClass, Map<com.palantir.conjure.spec.TypeName, TypeDefinition> typeDefinitions, TypeMapper typeMapper, TypeMapper returnTypeMapper) {
MethodSpec.Builder handleMethodBuilder = MethodSpec.methodBuilder("handleRequest").addAnnotation(Override.class).addModifiers(Modifier.PUBLIC).addParameter(HttpServerExchange.class, EXCHANGE_VAR_NAME).addException(IOException.class).addCode(endpointInvocation(endpointDefinition, typeDefinitions, typeMapper, returnTypeMapper));
endpointDefinition.getDeprecated().ifPresent(deprecatedDocsValue -> handleMethodBuilder.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "$S", "deprecation").build()));
MethodSpec.Builder ctorBuilder = MethodSpec.constructorBuilder().addParameter(UndertowRuntime.class, RUNTIME_VAR_NAME).addParameter(serviceClass, DELEGATE_VAR_NAME).addStatement("this.$1N = $1N", RUNTIME_VAR_NAME).addStatement("this.$1N = $1N", DELEGATE_VAR_NAME);
TypeSpec.Builder endpointBuilder = TypeSpec.classBuilder(endpointToHandlerClassName(endpointDefinition.getEndpointName())).addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL).addSuperinterface(HttpHandler.class).addSuperinterface(Endpoint.class).addField(FieldSpec.builder(UndertowRuntime.class, RUNTIME_VAR_NAME, Modifier.PRIVATE, Modifier.FINAL).build()).addField(FieldSpec.builder(serviceClass, DELEGATE_VAR_NAME, Modifier.PRIVATE, Modifier.FINAL).build());
addTags(endpointDefinition, endpointBuilder);
getBodyParamTypeArgument(endpointDefinition.getArgs()).map(ArgumentDefinition::getType).flatMap(type -> {
Type dealiased = TypeFunctions.toConjureTypeWithoutAliases(type, typeDefinitions);
return TypeFunctions.isBinaryOrOptionalBinary(dealiased) ? Optional.empty() : Optional.of(type);
}).map(typeMapper::getClassName).map(TypeName::box).map(this::immutableCollection).ifPresent(typeName -> {
TypeName type = ParameterizedTypeName.get(ClassName.get(Deserializer.class), typeName);
endpointBuilder.addField(FieldSpec.builder(type, DESERIALIZER_VAR_NAME, Modifier.PRIVATE, Modifier.FINAL).build());
ctorBuilder.addStatement("this.$1N = $2N.bodySerDe().deserializer(new $3T() {}, this)", DESERIALIZER_VAR_NAME, RUNTIME_VAR_NAME, ParameterizedTypeName.get(ClassName.get(TypeMarker.class), typeName));
});
endpointDefinition.getReturns().ifPresent(returnType -> {
Type dealiased = TypeFunctions.toConjureTypeWithoutAliases(returnType, typeDefinitions);
if (!TypeFunctions.isBinaryOrOptionalBinary(dealiased)) {
TypeName typeName = returnTypeMapper.getClassName(returnType).box();
TypeName type = ParameterizedTypeName.get(ClassName.get(Serializer.class), typeName);
endpointBuilder.addField(FieldSpec.builder(type, SERIALIZER_VAR_NAME, Modifier.PRIVATE, Modifier.FINAL).build());
ctorBuilder.addStatement("this.$1N = $2N.bodySerDe().serializer(new $3T() {}, this)", SERIALIZER_VAR_NAME, RUNTIME_VAR_NAME, ParameterizedTypeName.get(ClassName.get(TypeMarker.class), typeName));
}
});
endpointBuilder.addMethod(ctorBuilder.build()).addMethod(handleMethodBuilder.build());
if (UndertowTypeFunctions.isAsync(endpointDefinition, options)) {
ParameterizedTypeName type = UndertowTypeFunctions.getAsyncReturnType(endpointDefinition, returnTypeMapper, options);
TypeName resultType = Iterables.getOnlyElement(type.typeArguments);
endpointBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(ReturnValueWriter.class), resultType));
endpointBuilder.addMethod(MethodSpec.methodBuilder("write").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).addParameter(resultType, RESULT_VAR_NAME).addParameter(HttpServerExchange.class, EXCHANGE_VAR_NAME).addException(IOException.class).addCode(generateReturnValueCodeBlock(endpointDefinition, typeDefinitions)).build());
}
endpointBuilder.addMethod(MethodSpec.methodBuilder("method").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).returns(HttpString.class).addStatement("return $1T.$2N", Methods.class, endpointDefinition.getHttpMethod().toString()).build()).addMethod(MethodSpec.methodBuilder("template").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).returns(String.class).addStatement("return $1S", endpointDefinition.getHttpPath()).build()).addMethod(MethodSpec.methodBuilder("serviceName").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).returns(String.class).addStatement("return $1S", serviceDefinition.getServiceName().getName()).build()).addMethod(MethodSpec.methodBuilder("name").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).returns(String.class).addStatement("return $1S", endpointDefinition.getEndpointName().get()).build()).addMethod(MethodSpec.methodBuilder("handler").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).returns(HttpHandler.class).addStatement("return this").build());
endpointDefinition.getDeprecated().ifPresent(documentation -> endpointBuilder.addMethod(MethodSpec.methodBuilder("deprecated").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).returns(ParameterizedTypeName.get(ClassName.get(Optional.class), ClassName.get(String.class))).addStatement("return $1T.of($2S)", Optional.class, documentation).build()));
return endpointBuilder.build();
}
use of com.palantir.conjure.spec.Type in project conjure-java by palantir.
the class UndertowServiceHandlerGenerator method generateReturnValueCodeBlock.
private CodeBlock generateReturnValueCodeBlock(EndpointDefinition endpointDefinition, Map<com.palantir.conjure.spec.TypeName, TypeDefinition> typeDefinitions) {
CodeBlock.Builder code = CodeBlock.builder();
if (endpointDefinition.getReturns().isPresent()) {
Type returnType = endpointDefinition.getReturns().get();
// optional<> handling
Type dealiased = TypeFunctions.toConjureTypeWithoutAliases(returnType, typeDefinitions);
if (dealiased.accept(TypeVisitor.IS_OPTIONAL)) {
CodeBlock serializer;
if (TypeFunctions.isBinaryOrOptionalBinary(dealiased)) {
serializer = CodeBlock.builder().add(dealiased.accept(TypeVisitor.IS_BINARY) ? "$1N.bodySerDe().serialize($2N, $3N)" : "$1N.bodySerDe().serialize($2N.get(), $3N)", RUNTIME_VAR_NAME, RESULT_VAR_NAME, EXCHANGE_VAR_NAME).build();
} else {
serializer = CodeBlock.builder().add("$1N.serialize($2N, $3N)", SERIALIZER_VAR_NAME, RESULT_VAR_NAME, EXCHANGE_VAR_NAME).build();
}
// For optional<>: set response code to 204/NO_CONTENT if result is absent
code.add(CodeBlock.builder().beginControlFlow("if ($1L)", createIsOptionalPresentCall(TypeFunctions.isBinaryOrOptionalBinary(dealiased) ? dealiased : returnType, RESULT_VAR_NAME, typeDefinitions)).addStatement(serializer).nextControlFlow("else").addStatement("$1N.setStatusCode($2T.NO_CONTENT)", EXCHANGE_VAR_NAME, StatusCodes.class).endControlFlow().build());
} else {
if (dealiased.accept(TypeVisitor.IS_BINARY)) {
code.addStatement("$1N.bodySerDe().serialize($2N, $3N)", RUNTIME_VAR_NAME, RESULT_VAR_NAME, EXCHANGE_VAR_NAME);
} else {
code.addStatement("$1N.serialize($2N, $3N)", SERIALIZER_VAR_NAME, RESULT_VAR_NAME, EXCHANGE_VAR_NAME);
}
}
} else {
// Set 204 response code for void methods
// Use the constant from undertow for improved source readability, javac will compile it out.
code.addStatement("$1N.setStatusCode($2T.NO_CONTENT)", EXCHANGE_VAR_NAME, StatusCodes.class);
}
return code.build();
}
use of com.palantir.conjure.spec.Type in project conjure-java by palantir.
the class DefaultStaticFactoryMethodGenerator method clientImpl.
private MethodSpec clientImpl(EndpointDefinition def) {
List<ParameterSpec> params = parameterTypes.implementationMethodParams(def);
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(def.getEndpointName().get()).addModifiers(Modifier.PUBLIC).addParameters(params).addAnnotation(Override.class);
if (def.getDeprecated().isPresent()) {
methodBuilder.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "$S", "deprecation").build());
}
TypeName returnType = methodType.switchBy(returnTypes.baseType(def.getReturns()), returnTypes.async(def.getReturns()));
methodBuilder.returns(returnType);
CodeBlock.Builder requestParams = CodeBlock.builder();
def.getAuth().map(DefaultStaticFactoryMethodGenerator::generateAuthHeader).ifPresent(requestParams::add);
def.getArgs().stream().map(param -> generateParam(def.getEndpointName().get(), param)).forEach(requestParams::add);
CodeBlock request = CodeBlock.builder().add("$T $L = $T.builder();", Request.Builder.class, REQUEST, Request.class).add(requestParams.build()).build();
String codeBlock = methodType.switchBy("$L.clients().callBlocking($L, $L.build(), $L);", "$L.clients().call($L, $L.build" + "(), $L);");
CodeBlock execute = CodeBlock.of(codeBlock, StaticFactoryMethodGenerator.RUNTIME, Names.endpointChannel(def), REQUEST, def.getReturns().filter(type -> isBinaryOrOptionalBinary(returnTypes.baseType(type), returnTypes)).map(type -> StaticFactoryMethodGenerator.RUNTIME + (isOptionalBinary(returnTypes.baseType(type), returnTypes) ? ".bodySerDe().optionalInputStreamDeserializer()" : ".bodySerDe().inputStreamDeserializer()")).orElseGet(() -> def.getEndpointName().get() + "Deserializer"));
methodBuilder.addCode(request);
methodBuilder.addCode(methodType.switchBy(def.getReturns().isPresent() ? "return " : "", "return "));
methodBuilder.addCode(execute);
return methodBuilder.build();
}
use of com.palantir.conjure.spec.Type in project conjure-java by palantir.
the class BeanBuilderAuxiliarySettersUtils method widenParameterIfPossible.
public static TypeName widenParameterIfPossible(TypeName current, Type type, TypeMapper typeMapper) {
if (type.accept(TypeVisitor.IS_LIST)) {
Type innerType = type.accept(TypeVisitor.LIST).getItemType();
TypeName innerTypeName = typeMapper.getClassName(innerType).box();
if (isWidenableContainedType(innerType)) {
innerTypeName = WildcardTypeName.subtypeOf(innerTypeName);
}
return ParameterizedTypeName.get(ClassName.get(Iterable.class), innerTypeName);
}
if (type.accept(TypeVisitor.IS_SET)) {
Type innerType = type.accept(TypeVisitor.SET).getItemType();
TypeName innerTypeName = typeMapper.getClassName(innerType).box();
if (isWidenableContainedType(innerType)) {
innerTypeName = WildcardTypeName.subtypeOf(innerTypeName);
}
return ParameterizedTypeName.get(ClassName.get(Iterable.class), innerTypeName);
}
if (type.accept(TypeVisitor.IS_OPTIONAL)) {
Type innerType = type.accept(TypeVisitor.OPTIONAL).getItemType();
if (!isWidenableContainedType(innerType)) {
return current;
}
TypeName innerTypeName = typeMapper.getClassName(innerType).box();
return ParameterizedTypeName.get(ClassName.get(Optional.class), WildcardTypeName.subtypeOf(innerTypeName));
}
return current;
}
use of com.palantir.conjure.spec.Type in project conjure-java by palantir.
the class BeanGenerator method generateStageInterfaces.
private static List<TypeSpec> generateStageInterfaces(ClassName objectClass, ClassName builderClass, TypeMapper typeMapper, ImmutableList<EnrichedField> fieldsNeedingBuilderStage, ImmutableList<EnrichedField> otherFields) {
List<TypeSpec.Builder> interfaces = new ArrayList<>();
PeekingIterator<EnrichedField> fieldPeekingIterator = Iterators.peekingIterator(sortedEnrichedFields(fieldsNeedingBuilderStage).iterator());
while (fieldPeekingIterator.hasNext()) {
EnrichedField field = fieldPeekingIterator.next();
String nextBuilderStageName = fieldPeekingIterator.hasNext() ? JavaNameSanitizer.sanitize(fieldPeekingIterator.peek().fieldName()) : "completed_";
ClassName nextStageClassName = stageBuilderInterfaceName(objectClass, nextBuilderStageName);
interfaces.add(TypeSpec.interfaceBuilder(stageBuilderInterfaceName(objectClass, JavaNameSanitizer.sanitize(field.fieldName()))).addModifiers(Modifier.PUBLIC).addMethod(MethodSpec.methodBuilder(JavaNameSanitizer.sanitize(field.fieldName())).addParameter(ParameterSpec.builder(field.poetSpec().type, JavaNameSanitizer.sanitize(field.fieldName())).addAnnotation(Nonnull.class).build()).addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT).returns(nextStageClassName.box()).build()));
}
ClassName completedStageClass = stageBuilderInterfaceName(objectClass, "completed_");
TypeSpec.Builder completedStage = TypeSpec.interfaceBuilder(completedStageClass).addModifiers(Modifier.PUBLIC).addMethod(MethodSpec.methodBuilder("build").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT).returns(objectClass.box()).build());
completedStage.addMethods(otherFields.stream().map(field -> generateMethodsForFinalStageField(field, typeMapper, completedStageClass)).flatMap(List::stream).collect(Collectors.toList()));
interfaces.add(completedStage);
interfaces.get(0).addMethod(MethodSpec.methodBuilder("from").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT).returns(builderClass).addParameter(objectClass, "other").build());
return interfaces.stream().map(TypeSpec.Builder::build).collect(Collectors.toList());
}
Aggregations