diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/JerseyServiceGenerator.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/JerseyServiceGenerator.java index 0cf9a5e3e..4345cabad 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/JerseyServiceGenerator.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/JerseyServiceGenerator.java @@ -23,8 +23,7 @@ import com.google.common.collect.Lists; import com.palantir.conjure.java.ConjureAnnotations; import com.palantir.conjure.java.FeatureFlags; -import com.palantir.conjure.java.types.JerseyMethodTypeClassNameVisitor; -import com.palantir.conjure.java.types.JerseyReturnTypeClassNameVisitor; +import com.palantir.conjure.java.types.BinaryResolvingClassNameVisitor; import com.palantir.conjure.java.types.TypeMapper; import com.palantir.conjure.spec.ArgumentDefinition; import com.palantir.conjure.spec.AuthType; @@ -53,6 +52,7 @@ import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.TypeSpec; +import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -65,9 +65,12 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; import javax.lang.model.element.Modifier; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; import org.apache.commons.lang3.StringUtils; public final class JerseyServiceGenerator implements ServiceGenerator { + private static final ClassName NOT_NULL = ClassName.get("javax.validation.constraints", "NotNull"); private final Set experimentalFeatures; @@ -82,11 +85,15 @@ public JerseyServiceGenerator(Set experimentalFeatures) { @Override public Set generate(ConjureDefinition conjureDefinition) { + Class binaryReturnType = experimentalFeatures.contains(FeatureFlags.JerseyBinaryAsResponse) + ? Response.class + : StreamingOutput.class; TypeMapper returnTypeMapper = new TypeMapper( conjureDefinition.getTypes(), - types -> new JerseyReturnTypeClassNameVisitor(types, experimentalFeatures)); + BinaryResolvingClassNameVisitor.createFactory(binaryReturnType)); TypeMapper methodTypeMapper = new TypeMapper( - conjureDefinition.getTypes(), JerseyMethodTypeClassNameVisitor::new); + conjureDefinition.getTypes(), + BinaryResolvingClassNameVisitor.createFactory(InputStream.class)); return conjureDefinition.getServices().stream() .map(serviceDef -> generateService(serviceDef, returnTypeMapper, methodTypeMapper)) .collect(Collectors.toSet()); diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/Retrofit2ServiceGenerator.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/Retrofit2ServiceGenerator.java index bbb1ffd41..f78a63d1c 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/Retrofit2ServiceGenerator.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/Retrofit2ServiceGenerator.java @@ -23,8 +23,7 @@ import com.google.common.collect.Lists; import com.palantir.conjure.java.ConjureAnnotations; import com.palantir.conjure.java.FeatureFlags; -import com.palantir.conjure.java.types.Retrofit2MethodTypeClassNameVisitor; -import com.palantir.conjure.java.types.Retrofit2ReturnTypeClassNameVisitor; +import com.palantir.conjure.java.types.BinaryResolvingClassNameVisitor; import com.palantir.conjure.java.types.TypeMapper; import com.palantir.conjure.spec.ArgumentDefinition; import com.palantir.conjure.spec.ArgumentName; @@ -47,6 +46,7 @@ import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.ParameterizedTypeName; +import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; import java.util.List; import java.util.Optional; @@ -68,8 +68,8 @@ public final class Retrofit2ServiceGenerator implements ServiceGenerator { private static final ClassName CALL_TYPE = ClassName.get("retrofit2", "Call"); private static final String AUTH_HEADER_NAME = "Authorization"; - private static final String JSON_MEDIA_TYPE = MediaType.APPLICATION_JSON; - private static final String OCTET_STREAM_MEDIA_TYPE = MediaType.APPLICATION_OCTET_STREAM; + private static final ClassName BINARY_METHOD_TYPE = ClassName.get("okhttp3", "RequestBody"); + private static final ClassName BINARY_RETURN_TYPE = ClassName.get("okhttp3", "ResponseBody"); private static final Logger log = LoggerFactory.getLogger(Retrofit2ServiceGenerator.class); @@ -85,10 +85,12 @@ public Retrofit2ServiceGenerator(Set experimentalFeatures) { @Override public Set generate(ConjureDefinition conjureDefinition) { - TypeMapper returnTypeMapper = - new TypeMapper(conjureDefinition.getTypes(), Retrofit2ReturnTypeClassNameVisitor::new); - TypeMapper methodTypeMapper = - new TypeMapper(conjureDefinition.getTypes(), Retrofit2MethodTypeClassNameVisitor::new); + TypeMapper returnTypeMapper = new TypeMapper( + conjureDefinition.getTypes(), + BinaryResolvingClassNameVisitor.createFactory(BINARY_RETURN_TYPE)); + TypeMapper methodTypeMapper = new TypeMapper( + conjureDefinition.getTypes(), + BinaryResolvingClassNameVisitor.createFactory(BINARY_METHOD_TYPE)); return conjureDefinition.getServices().stream() .map(serviceDef -> generateService(serviceDef, returnTypeMapper, methodTypeMapper)) .collect(Collectors.toSet()); @@ -131,25 +133,23 @@ private MethodSpec generateServiceMethod( EndpointDefinition endpointDef, TypeMapper returnTypeMapper, TypeMapper methodTypeMapper) { + TypeName returnType = endpointDef.getReturns() + .map(returnTypeMapper::getClassName) + .orElse(ClassName.VOID); + Set encodedPathArgs = extractEncodedPathArgs(endpointDef.getHttpPath()); HttpPath endpointPathWithoutRegex = replaceEncodedPathArgs(endpointDef.getHttpPath()); MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(endpointDef.getEndpointName().get()) .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) .addAnnotation(AnnotationSpec.builder(httpMethodToClassName(endpointDef.getHttpMethod().get().name())) .addMember("value", "$S", "." + endpointPathWithoutRegex) + .build()) + .addAnnotation(AnnotationSpec.builder(ClassName.get("retrofit2.http", "Headers")) + .addMember("value", "$S", "hr-path-template: " + endpointPathWithoutRegex) + .addMember("value", "$S", "Accept: " + getReturnMediaType(returnType)) .build()); - AnnotationSpec.Builder headersBuilder = AnnotationSpec.builder(ClassName.get("retrofit2.http", "Headers")) - .addMember("value", "$S", "hr-path-template: " + endpointPathWithoutRegex); - endpointDef.getReturns().ifPresent(type -> { - String mediaType = type.accept(TypeVisitor.IS_BINARY) - ? MediaType.APPLICATION_OCTET_STREAM - : MediaType.APPLICATION_JSON; - headersBuilder.addMember("value", "$S", "Accept: " + mediaType); - }); - methodBuilder.addAnnotation(headersBuilder.build()); - - if (endpointDef.getReturns().map(type -> type.accept(TypeVisitor.IS_BINARY)).orElse(false)) { + if (returnType.equals(BINARY_RETURN_TYPE)) { methodBuilder.addAnnotation(AnnotationSpec.builder(ClassName.get("retrofit2.http", "Streaming")).build()); } @@ -159,13 +159,7 @@ private MethodSpec generateServiceMethod( ServiceGenerator.getJavaDoc(endpointDef).ifPresent( content -> methodBuilder.addJavadoc("$L", content)); - if (endpointDef.getReturns().isPresent()) { - methodBuilder.returns( - ParameterizedTypeName.get(getReturnType(), - returnTypeMapper.getClassName(endpointDef.getReturns().get()).box())); - } else { - methodBuilder.returns(ParameterizedTypeName.get(getReturnType(), ClassName.get(Void.class))); - } + methodBuilder.returns(ParameterizedTypeName.get(getReturnType(), returnType.box())); getAuthParameter(endpointDef.getAuth()).ifPresent(methodBuilder::addParameter); @@ -260,6 +254,12 @@ private Optional getAuthParameter(Optional auth) { throw new IllegalStateException("Unrecognized auth type: " + auth.get()); } + private static String getReturnMediaType(TypeName returnType) { + return returnType.equals(BINARY_RETURN_TYPE) + ? MediaType.APPLICATION_OCTET_STREAM + : MediaType.APPLICATION_JSON; + } + private static Set createMarkers(TypeMapper typeMapper, List markers) { checkArgument(markers.stream().allMatch(type -> type.accept(TypeVisitor.IS_REFERENCE)), "Markers must refer to reference types."); diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/Retrofit2ReturnTypeClassNameVisitor.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/BinaryResolvingClassNameVisitor.java similarity index 63% rename from conjure-java-core/src/main/java/com/palantir/conjure/java/types/Retrofit2ReturnTypeClassNameVisitor.java rename to conjure-java-core/src/main/java/com/palantir/conjure/java/types/BinaryResolvingClassNameVisitor.java index 27276d05d..4929db269 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/Retrofit2ReturnTypeClassNameVisitor.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/BinaryResolvingClassNameVisitor.java @@ -16,13 +16,13 @@ package com.palantir.conjure.java.types; -import com.palantir.conjure.java.util.BinaryReturnTypeResolver; import com.palantir.conjure.spec.ExternalReference; import com.palantir.conjure.spec.ListType; import com.palantir.conjure.spec.MapType; import com.palantir.conjure.spec.OptionalType; import com.palantir.conjure.spec.PrimitiveType; import com.palantir.conjure.spec.SetType; +import com.palantir.conjure.spec.Type; import com.palantir.conjure.spec.TypeDefinition; import com.palantir.conjure.visitor.TypeDefinitionVisitor; import com.squareup.javapoet.ClassName; @@ -32,17 +32,26 @@ import java.util.function.Function; import java.util.stream.Collectors; -public final class Retrofit2ReturnTypeClassNameVisitor implements ClassNameVisitor { - - private static final ClassName RESPONSE_BODY_TYPE = ClassName.get("okhttp3", "ResponseBody"); +public final class BinaryResolvingClassNameVisitor implements ClassNameVisitor { private final DefaultClassNameVisitor delegate; private final Map types; + private final ClassName binaryClassName; + + public static Factory createFactory(Class binaryClass) { + return createFactory(ClassName.get(binaryClass)); + } + + public static Factory createFactory(ClassName binaryClassName) { + return types -> new BinaryResolvingClassNameVisitor(types, binaryClassName); + } - public Retrofit2ReturnTypeClassNameVisitor(List types) { - this.types = types.stream().collect( - Collectors.toMap(t -> t.accept(TypeDefinitionVisitor.TYPE_NAME), Function.identity())); + private BinaryResolvingClassNameVisitor(List types, ClassName binaryClassName) { this.delegate = new DefaultClassNameVisitor(types); + this.types = types.stream().collect(Collectors.toMap( + t -> t.accept(TypeDefinitionVisitor.TYPE_NAME), + Function.identity())); + this.binaryClassName = binaryClassName; } @Override @@ -63,7 +72,7 @@ public TypeName visitOptional(OptionalType type) { @Override public TypeName visitPrimitive(PrimitiveType type) { if (type.get() == PrimitiveType.Value.BINARY) { - return RESPONSE_BODY_TYPE; + return binaryClassName; } else { return delegate.visitPrimitive(type); } @@ -71,7 +80,20 @@ public TypeName visitPrimitive(PrimitiveType type) { @Override public TypeName visitReference(com.palantir.conjure.spec.TypeName type) { - return BinaryReturnTypeResolver.resolveReturnReferenceType(types, type, RESPONSE_BODY_TYPE); + if (!types.containsKey(type)) { + throw new IllegalStateException("Unknown LocalReferenceType type: " + type); + } + + TypeDefinition def = types.get(type); + if (def.accept(TypeDefinitionVisitor.IS_ALIAS)) { + Type aliasType = def.accept(TypeDefinitionVisitor.ALIAS).getAlias(); + TypeName aliasClassName = aliasType.accept(this); + if (aliasClassName.equals(binaryClassName)) { + return binaryClassName; + } + } + + return delegate.visitReference(type); } @Override @@ -83,5 +105,4 @@ public TypeName visitExternal(ExternalReference type) { public TypeName visitSet(SetType type) { return delegate.visitSet(type); } - } diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/JerseyMethodTypeClassNameVisitor.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/JerseyMethodTypeClassNameVisitor.java deleted file mode 100644 index a033805ae..000000000 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/JerseyMethodTypeClassNameVisitor.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * (c) Copyright 2018 Palantir Technologies Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.palantir.conjure.java.types; - -import com.palantir.conjure.spec.ExternalReference; -import com.palantir.conjure.spec.ListType; -import com.palantir.conjure.spec.MapType; -import com.palantir.conjure.spec.OptionalType; -import com.palantir.conjure.spec.PrimitiveType; -import com.palantir.conjure.spec.SetType; -import com.palantir.conjure.spec.TypeDefinition; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.TypeName; -import java.io.InputStream; -import java.util.List; - -public final class JerseyMethodTypeClassNameVisitor implements ClassNameVisitor { - - private final DefaultClassNameVisitor delegate; - - public JerseyMethodTypeClassNameVisitor(List types) { - this.delegate = new DefaultClassNameVisitor(types); - } - - @Override - public TypeName visitList(ListType type) { - return delegate.visitList(type); - } - - @Override - public TypeName visitMap(MapType type) { - return delegate.visitMap(type); - } - - @Override - public TypeName visitOptional(OptionalType type) { - return delegate.visitOptional(type); - } - - @Override - public TypeName visitPrimitive(PrimitiveType type) { - if (type.get() == PrimitiveType.Value.BINARY) { - return ClassName.get(InputStream.class); - } else { - return delegate.visitPrimitive(type); - } - } - - @Override - public TypeName visitReference(com.palantir.conjure.spec.TypeName type) { - return delegate.visitReference(type); - } - - @Override - public TypeName visitExternal(ExternalReference type) { - return delegate.visitExternal(type); - } - - @Override - public TypeName visitSet(SetType type) { - return delegate.visitSet(type); - } -} diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/JerseyReturnTypeClassNameVisitor.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/JerseyReturnTypeClassNameVisitor.java deleted file mode 100644 index 6088f20e2..000000000 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/JerseyReturnTypeClassNameVisitor.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * (c) Copyright 2018 Palantir Technologies Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.palantir.conjure.java.types; - -import com.palantir.conjure.java.FeatureFlags; -import com.palantir.conjure.java.util.BinaryReturnTypeResolver; -import com.palantir.conjure.spec.ExternalReference; -import com.palantir.conjure.spec.ListType; -import com.palantir.conjure.spec.MapType; -import com.palantir.conjure.spec.OptionalType; -import com.palantir.conjure.spec.PrimitiveType; -import com.palantir.conjure.spec.SetType; -import com.palantir.conjure.spec.TypeDefinition; -import com.palantir.conjure.visitor.TypeDefinitionVisitor; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.TypeName; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.StreamingOutput; - -public final class JerseyReturnTypeClassNameVisitor implements ClassNameVisitor { - - private final boolean binaryAsResponse; - private final DefaultClassNameVisitor delegate; - private final Map types; - - public JerseyReturnTypeClassNameVisitor(List types, Set featureFlags) { - this.types = types.stream().collect( - Collectors.toMap(t -> t.accept(TypeDefinitionVisitor.TYPE_NAME), Function.identity())); - this.delegate = new DefaultClassNameVisitor(types); - this.binaryAsResponse = featureFlags.contains(FeatureFlags.JerseyBinaryAsResponse); - } - - @Override - public TypeName visitList(ListType type) { - return delegate.visitList(type); - } - - @Override - public TypeName visitMap(MapType type) { - return delegate.visitMap(type); - } - - @Override - public TypeName visitOptional(OptionalType type) { - return delegate.visitOptional(type); - } - - @Override - public TypeName visitPrimitive(PrimitiveType type) { - if (type.get() == PrimitiveType.Value.BINARY) { - if (binaryAsResponse) { - return ClassName.get(Response.class); - } else { - return ClassName.get(StreamingOutput.class); - } - } - return delegate.visitPrimitive(type); - } - - @Override - public TypeName visitReference(com.palantir.conjure.spec.TypeName type) { - return BinaryReturnTypeResolver.resolveReturnReferenceType(types, type, - binaryAsResponse ? ClassName.get(Response.class) : ClassName.get(StreamingOutput.class)); - } - - @Override - public TypeName visitExternal(ExternalReference type) { - return delegate.visitExternal(type); - } - - @Override - public TypeName visitSet(SetType type) { - return delegate.visitSet(type); - } - -} diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/Retrofit2MethodTypeClassNameVisitor.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/Retrofit2MethodTypeClassNameVisitor.java deleted file mode 100644 index 256eedc48..000000000 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/Retrofit2MethodTypeClassNameVisitor.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * (c) Copyright 2018 Palantir Technologies Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.palantir.conjure.java.types; - -import com.palantir.conjure.spec.ExternalReference; -import com.palantir.conjure.spec.ListType; -import com.palantir.conjure.spec.MapType; -import com.palantir.conjure.spec.OptionalType; -import com.palantir.conjure.spec.PrimitiveType; -import com.palantir.conjure.spec.SetType; -import com.palantir.conjure.spec.TypeDefinition; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.TypeName; -import java.util.List; - -public final class Retrofit2MethodTypeClassNameVisitor implements ClassNameVisitor { - - private static final ClassName REQUEST_BODY_TYPE = ClassName.get("okhttp3", "RequestBody"); - - private final DefaultClassNameVisitor delegate; - - public Retrofit2MethodTypeClassNameVisitor(List types) { - this.delegate = new DefaultClassNameVisitor(types); - } - - @Override - public TypeName visitList(ListType type) { - return delegate.visitList(type); - } - - @Override - public TypeName visitMap(MapType type) { - return delegate.visitMap(type); - } - - @Override - public TypeName visitOptional(OptionalType type) { - return delegate.visitOptional(type); - } - - @Override - public TypeName visitPrimitive(PrimitiveType type) { - if (type.get() == PrimitiveType.Value.BINARY) { - return REQUEST_BODY_TYPE; - } else { - return delegate.visitPrimitive(type); - } - } - - @Override - public TypeName visitReference(com.palantir.conjure.spec.TypeName type) { - return delegate.visitReference(type); - } - - @Override - public TypeName visitExternal(ExternalReference type) { - return delegate.visitExternal(type); - } - - @Override - public TypeName visitSet(SetType type) { - return delegate.visitSet(type); - } - -} diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/TypeMapper.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/TypeMapper.java index 5f850bd48..10aa8ae27 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/TypeMapper.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/TypeMapper.java @@ -37,8 +37,7 @@ public TypeMapper(List types) { this(types, DefaultClassNameVisitor::new); } - public TypeMapper(List types, - Factory classNameVisitorFactory) { + public TypeMapper(List types, Factory classNameVisitorFactory) { this.types = types.stream().collect( Collectors.toMap(t -> t.accept(TypeDefinitionVisitor.TYPE_NAME), Function.identity())); this.classNameVisitorFactory = classNameVisitorFactory; diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/util/BinaryReturnTypeResolver.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/util/BinaryReturnTypeResolver.java deleted file mode 100644 index f79f0ae33..000000000 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/util/BinaryReturnTypeResolver.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * (c) Copyright 2018 Palantir Technologies Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.palantir.conjure.java.util; - -import com.palantir.conjure.spec.AliasDefinition; -import com.palantir.conjure.spec.Type; -import com.palantir.conjure.spec.TypeDefinition; -import com.palantir.conjure.visitor.TypeDefinitionVisitor; -import com.palantir.conjure.visitor.TypeVisitor; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.TypeName; -import java.util.Map; - -public final class BinaryReturnTypeResolver { - - private BinaryReturnTypeResolver() {} - - /** - * Recursively examines nested local alias references to see if the leaf node is of a binary type. If so, - * this method resolves it to a binary type supplied by the {@code binaryTypeName}, otherwise it returns the - * immediate local reference {@code {@link TypeName}}. - * - * @param types - a map of name to conjure definition - * @param type - the given type to be resolved - * @param binaryTypeName - the return binary type name if the leaf node is of a binary type - * @return resolved return reference type - */ - public static TypeName resolveReturnReferenceType( - Map types, - com.palantir.conjure.spec.TypeName type, - TypeName binaryTypeName) { - - if (!types.containsKey(type)) { - throw new IllegalStateException("Unknown LocalReferenceType type: " + type); - } - - TypeDefinition def = types.get(type); - while (def.accept(TypeDefinitionVisitor.IS_ALIAS)) { - AliasDefinition aliasDefinition = def.accept(TypeDefinitionVisitor.ALIAS); - Type conjureType = aliasDefinition.getAlias(); - if (conjureType.accept(TypeVisitor.IS_REFERENCE)) { - def = types.get(conjureType.accept(TypeVisitor.REFERENCE)); - } else if (conjureType.accept(TypeVisitor.IS_BINARY)) { - return binaryTypeName; - } else { - break; - } - } - - return ClassName.get(type.getPackage(), type.getName()); - } -} diff --git a/conjure-java-core/src/test/resources/example-service.yml b/conjure-java-core/src/test/resources/example-service.yml index 0f33d769c..ce92f9b0a 100644 --- a/conjure-java-core/src/test/resources/example-service.yml +++ b/conjure-java-core/src/test/resources/example-service.yml @@ -122,6 +122,13 @@ services: type: binary param-type: body + uploadAliasedRawData: + http: POST /datasets/upload-raw-aliased + args: + input: + type: NestedAliasedBinary + param-type: body + getBranches: http: GET /datasets/{datasetRid}/branches args: diff --git a/conjure-java-core/src/test/resources/test/api/TestService.java.jersey b/conjure-java-core/src/test/resources/test/api/TestService.java.jersey index f4205c361..f3d7a0e42 100644 --- a/conjure-java-core/src/test/resources/test/api/TestService.java.jersey +++ b/conjure-java-core/src/test/resources/test/api/TestService.java.jersey @@ -87,6 +87,12 @@ public interface TestService { @HeaderParam("Authorization") @NotNull AuthHeader authHeader, @NotNull InputStream input); + @POST + @Path("catalog/datasets/upload-raw-aliased") + void uploadAliasedRawData( + @HeaderParam("Authorization") @NotNull AuthHeader authHeader, + @NotNull InputStream input); + @GET @Path("catalog/datasets/{datasetRid}/branches") Set getBranches( diff --git a/conjure-java-core/src/test/resources/test/api/TestService.java.jersey_require_not_null b/conjure-java-core/src/test/resources/test/api/TestService.java.jersey_require_not_null index f4205c361..f3d7a0e42 100644 --- a/conjure-java-core/src/test/resources/test/api/TestService.java.jersey_require_not_null +++ b/conjure-java-core/src/test/resources/test/api/TestService.java.jersey_require_not_null @@ -87,6 +87,12 @@ public interface TestService { @HeaderParam("Authorization") @NotNull AuthHeader authHeader, @NotNull InputStream input); + @POST + @Path("catalog/datasets/upload-raw-aliased") + void uploadAliasedRawData( + @HeaderParam("Authorization") @NotNull AuthHeader authHeader, + @NotNull InputStream input); + @GET @Path("catalog/datasets/{datasetRid}/branches") Set getBranches( diff --git a/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit b/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit index 688851a2d..9df8b5694 100644 --- a/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit +++ b/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit @@ -66,8 +66,9 @@ public interface TestServiceRetrofit { @GET("./catalog/datasets/{datasetRid}/raw-aliased") @Headers({ "hr-path-template: /catalog/datasets/{datasetRid}/raw-aliased", - "Accept: application/json" + "Accept: application/octet-stream" }) + @Streaming Call getAliasedRawData( @Header("Authorization") AuthHeader authHeader, @Path("datasetRid") ResourceIdentifier datasetRid); @@ -91,10 +92,15 @@ public interface TestServiceRetrofit { @Path("datasetRid") ResourceIdentifier datasetRid); @POST("./catalog/datasets/upload-raw") - @Headers("hr-path-template: /catalog/datasets/upload-raw") + @Headers({"hr-path-template: /catalog/datasets/upload-raw", "Accept: application/json"}) Call uploadRawData( @Header("Authorization") AuthHeader authHeader, @Body RequestBody input); + @POST("./catalog/datasets/upload-raw-aliased") + @Headers({"hr-path-template: /catalog/datasets/upload-raw-aliased", "Accept: application/json"}) + Call uploadAliasedRawData( + @Header("Authorization") AuthHeader authHeader, @Body RequestBody input); + @GET("./catalog/datasets/{datasetRid}/branches") @Headers({ "hr-path-template: /catalog/datasets/{datasetRid}/branches", @@ -150,7 +156,10 @@ public interface TestServiceRetrofit { @Query("optionalEnd") Optional optionalEnd); @POST("./catalog/test-no-response-query-params") - @Headers("hr-path-template: /catalog/test-no-response-query-params") + @Headers({ + "hr-path-template: /catalog/test-no-response-query-params", + "Accept: application/json" + }) Call testNoResponseQueryParams( @Header("Authorization") AuthHeader authHeader, @Body String query, @@ -178,7 +187,7 @@ public interface TestServiceRetrofit { @Header("Authorization") AuthHeader authHeader, @Body Optional maybeString); @GET("./catalog/optional-integer-double") - @Headers("hr-path-template: /catalog/optional-integer-double") + @Headers({"hr-path-template: /catalog/optional-integer-double", "Accept: application/json"}) Call testOptionalIntegerAndDouble( @Header("Authorization") AuthHeader authHeader, @Query("maybeInteger") OptionalInt maybeInteger, diff --git a/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit_completable_future b/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit_completable_future index a3f071ea5..fff62b99e 100644 --- a/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit_completable_future +++ b/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit_completable_future @@ -66,8 +66,9 @@ public interface TestServiceRetrofit { @GET("./catalog/datasets/{datasetRid}/raw-aliased") @Headers({ "hr-path-template: /catalog/datasets/{datasetRid}/raw-aliased", - "Accept: application/json" + "Accept: application/octet-stream" }) + @Streaming CompletableFuture getAliasedRawData( @Header("Authorization") AuthHeader authHeader, @Path("datasetRid") ResourceIdentifier datasetRid); @@ -91,10 +92,15 @@ public interface TestServiceRetrofit { @Path("datasetRid") ResourceIdentifier datasetRid); @POST("./catalog/datasets/upload-raw") - @Headers("hr-path-template: /catalog/datasets/upload-raw") + @Headers({"hr-path-template: /catalog/datasets/upload-raw", "Accept: application/json"}) CompletableFuture uploadRawData( @Header("Authorization") AuthHeader authHeader, @Body RequestBody input); + @POST("./catalog/datasets/upload-raw-aliased") + @Headers({"hr-path-template: /catalog/datasets/upload-raw-aliased", "Accept: application/json"}) + CompletableFuture uploadAliasedRawData( + @Header("Authorization") AuthHeader authHeader, @Body RequestBody input); + @GET("./catalog/datasets/{datasetRid}/branches") @Headers({ "hr-path-template: /catalog/datasets/{datasetRid}/branches", @@ -150,7 +156,10 @@ public interface TestServiceRetrofit { @Query("optionalEnd") Optional optionalEnd); @POST("./catalog/test-no-response-query-params") - @Headers("hr-path-template: /catalog/test-no-response-query-params") + @Headers({ + "hr-path-template: /catalog/test-no-response-query-params", + "Accept: application/json" + }) CompletableFuture testNoResponseQueryParams( @Header("Authorization") AuthHeader authHeader, @Body String query, @@ -178,7 +187,7 @@ public interface TestServiceRetrofit { @Header("Authorization") AuthHeader authHeader, @Body Optional maybeString); @GET("./catalog/optional-integer-double") - @Headers("hr-path-template: /catalog/optional-integer-double") + @Headers({"hr-path-template: /catalog/optional-integer-double", "Accept: application/json"}) CompletableFuture testOptionalIntegerAndDouble( @Header("Authorization") AuthHeader authHeader, @Query("maybeInteger") OptionalInt maybeInteger, diff --git a/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit_listenable_future b/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit_listenable_future index c2db14cca..afcd716c3 100644 --- a/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit_listenable_future +++ b/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit_listenable_future @@ -66,8 +66,9 @@ public interface TestServiceRetrofit { @GET("./catalog/datasets/{datasetRid}/raw-aliased") @Headers({ "hr-path-template: /catalog/datasets/{datasetRid}/raw-aliased", - "Accept: application/json" + "Accept: application/octet-stream" }) + @Streaming ListenableFuture getAliasedRawData( @Header("Authorization") AuthHeader authHeader, @Path("datasetRid") ResourceIdentifier datasetRid); @@ -91,10 +92,15 @@ public interface TestServiceRetrofit { @Path("datasetRid") ResourceIdentifier datasetRid); @POST("./catalog/datasets/upload-raw") - @Headers("hr-path-template: /catalog/datasets/upload-raw") + @Headers({"hr-path-template: /catalog/datasets/upload-raw", "Accept: application/json"}) ListenableFuture uploadRawData( @Header("Authorization") AuthHeader authHeader, @Body RequestBody input); + @POST("./catalog/datasets/upload-raw-aliased") + @Headers({"hr-path-template: /catalog/datasets/upload-raw-aliased", "Accept: application/json"}) + ListenableFuture uploadAliasedRawData( + @Header("Authorization") AuthHeader authHeader, @Body RequestBody input); + @GET("./catalog/datasets/{datasetRid}/branches") @Headers({ "hr-path-template: /catalog/datasets/{datasetRid}/branches", @@ -150,7 +156,10 @@ public interface TestServiceRetrofit { @Query("optionalEnd") Optional optionalEnd); @POST("./catalog/test-no-response-query-params") - @Headers("hr-path-template: /catalog/test-no-response-query-params") + @Headers({ + "hr-path-template: /catalog/test-no-response-query-params", + "Accept: application/json" + }) ListenableFuture testNoResponseQueryParams( @Header("Authorization") AuthHeader authHeader, @Body String query, @@ -178,7 +187,7 @@ public interface TestServiceRetrofit { @Header("Authorization") AuthHeader authHeader, @Body Optional maybeString); @GET("./catalog/optional-integer-double") - @Headers("hr-path-template: /catalog/optional-integer-double") + @Headers({"hr-path-template: /catalog/optional-integer-double", "Accept: application/json"}) ListenableFuture testOptionalIntegerAndDouble( @Header("Authorization") AuthHeader authHeader, @Query("maybeInteger") OptionalInt maybeInteger,