Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[jaxrs-spec] Add builders to models #4916

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
public static final String USE_SWAGGER_ANNOTATIONS = "useSwaggerAnnotations";
public static final String JACKSON = "jackson";
public static final String OPEN_API_SPEC_FILE_LOCATION = "openApiSpecFileLocation";
public static final String GENERATE_BUILDERS = "generateBuilders";

public static final String QUARKUS_LIBRARY = "quarkus";
public static final String THORNTAIL_LIBRARY = "thorntail";
Expand All @@ -51,6 +52,7 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
private boolean interfaceOnly = false;
private boolean returnResponse = false;
private boolean generatePom = true;
private boolean generateBuilders = false;
private boolean useSwaggerAnnotations = true;
private boolean useJackson = false;
private String openApiSpecFileLocation = "src/main/openapi/openapi.yaml";
Expand Down Expand Up @@ -102,6 +104,7 @@ public JavaJAXRSSpecServerCodegen() {

cliOptions.add(library);
cliOptions.add(CliOption.newBoolean(GENERATE_POM, "Whether to generate pom.xml if the file does not already exist.").defaultValue(String.valueOf(generatePom)));
cliOptions.add(CliOption.newBoolean(GENERATE_BUILDERS, "Whether to generate builders for models.").defaultValue(String.valueOf(generateBuilders)));
cliOptions.add(CliOption.newBoolean(INTERFACE_ONLY, "Whether to generate only API interface stubs without the server files.").defaultValue(String.valueOf(interfaceOnly)));
cliOptions.add(CliOption.newBoolean(RETURN_RESPONSE, "Whether generate API interface should return javax.ws.rs.core.Response instead of a deserialized entity. Only useful if interfaceOnly is true.").defaultValue(String.valueOf(returnResponse)));
cliOptions.add(CliOption.newBoolean(USE_SWAGGER_ANNOTATIONS, "Whether to generate Swagger annotations.", useSwaggerAnnotations));
Expand All @@ -125,14 +128,20 @@ public void processOpts() {
additionalProperties.remove(RETURN_RESPONSE);
}
}
if(QUARKUS_LIBRARY.equals(library) || THORNTAIL_LIBRARY.equals(library) || HELIDON_LIBRARY.equals(library) || OPEN_LIBERTY_LIBRARY.equals(library)) {
if (QUARKUS_LIBRARY.equals(library) || THORNTAIL_LIBRARY.equals(library) || HELIDON_LIBRARY.equals(library) || OPEN_LIBERTY_LIBRARY.equals(library)) {
useSwaggerAnnotations = false;
} else {
if (additionalProperties.containsKey(USE_SWAGGER_ANNOTATIONS)) {
useSwaggerAnnotations = Boolean.valueOf(additionalProperties.get(USE_SWAGGER_ANNOTATIONS).toString());
}
}
writePropertyBack(USE_SWAGGER_ANNOTATIONS, useSwaggerAnnotations);

if (additionalProperties.containsKey(GENERATE_BUILDERS)) {
generateBuilders = Boolean.valueOf(additionalProperties.get(GENERATE_BUILDERS).toString());
}
additionalProperties.put(GENERATE_BUILDERS, generateBuilders);

if (additionalProperties.containsKey(OPEN_API_SPEC_FILE_LOCATION)) {
openApiSpecFileLocation = additionalProperties.get(OPEN_API_SPEC_FILE_LOCATION).toString();
} else if(QUARKUS_LIBRARY.equals(library) || THORNTAIL_LIBRARY.equals(library) || HELIDON_LIBRARY.equals(library)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,52 +1,38 @@
{{#useSwaggerAnnotations}}
import io.swagger.annotations.*;
{{/useSwaggerAnnotations}}
{{#useSwaggerAnnotations}}import io.swagger.annotations.*;{{/useSwaggerAnnotations}}
shybovycha marked this conversation as resolved.
Show resolved Hide resolved
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{#description}}
/**
{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{#description}}/**
* {{description}}
**/{{/description}}{{#useSwaggerAnnotations}}
{{#description}}{{>additionalModelTypeAnnotations}}@ApiModel(description = "{{{description}}}"){{/description}}{{/useSwaggerAnnotations}}
**/{{/description}}
{{#useSwaggerAnnotations}}{{#description}}{{>additionalModelTypeAnnotations}}@ApiModel(description = "{{{description}}}"){{/description}}{{/useSwaggerAnnotations}}
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#serializableModel}}implements Serializable{{/serializableModel}} {
{{#vars}}{{#isEnum}}{{^isContainer}}

{{>enumClass}}{{/isContainer}}{{#isContainer}}{{#mostInnerItems}}

{{>enumClass}}{{/mostInnerItems}}{{/isContainer}}{{/isEnum}}
private {{#useBeanValidation}}@Valid{{/useBeanValidation}} {{{datatypeWithEnum}}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};{{/vars}}
private {{#useBeanValidation}}@Valid {{/useBeanValidation}}{{{datatypeWithEnum}}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};{{/vars}}

{{#vars}}
/**
{{#description}}
* {{description}}
{{/description}}
{{#minimum}}
* minimum: {{minimum}}
{{/minimum}}
{{#maximum}}
* maximum: {{maximum}}
{{/maximum}}
**/
public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) {
{{#generateBuilders}}public {{classname}}({{#vars}}{{{datatypeWithEnum}}} {{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}) {
{{#vars}}
this.{{name}} = {{name}};
return this;
{{/vars}}
}
{{/generateBuilders}}

{{#vendorExtensions.extraAnnotation}}{{{vendorExtensions.extraAnnotation}}}{{/vendorExtensions.extraAnnotation}}{{#useSwaggerAnnotations}}
{{#vars}}{{#vendorExtensions.extraAnnotation}}{{{vendorExtensions.extraAnnotation}}}{{/vendorExtensions.extraAnnotation}}{{#useSwaggerAnnotations}}
@ApiModelProperty({{#example}}example = "{{{example}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}value = "{{{description}}}"){{/useSwaggerAnnotations}}
@JsonProperty("{{baseName}}")
{{#useBeanValidation}}{{>beanValidation}}{{/useBeanValidation}} public {{{datatypeWithEnum}}} {{getter}}() {
return {{name}};
}

public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {
this.{{name}} = {{name}};
}

{{/vars}}
}{{/vars}}

@Override
public boolean equals(java.lang.Object o) {
Expand Down Expand Up @@ -88,4 +74,37 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#seriali
}
return o.toString().replace("\n", "\n ");
}

{{#generateBuilders}}
public static Builder builder() {
return new Builder();
}

public static class Builder {
{{#vars}}
private {{{datatypeWithEnum}}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};
{{/vars}}

{{#vars}}
/**
{{#description}}
* {{description}}
{{/description}}
{{#minimum}}
* minimum: {{minimum}}
{{/minimum}}
{{#maximum}}
* maximum: {{maximum}}
{{/maximum}}
**/
public Builder {{name}}({{{datatypeWithEnum}}} {{name}}) {
this.{{name}} = {{name}};
return this;
}
{{/vars}}

public {{classname}} build() {
return new {{classname}}({{#vars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/vars}});
}
}{{/generateBuilders}}
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.0-SNAPSHOT
4.3.0-SNAPSHOT
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ public interface AnotherFakeApi {
@ApiOperation(value = "To test special tags", notes = "To test special tags and operation ID starting with number", tags={ "$another-fake?" })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Client.class) })
Response call123testSpecialTags(@Valid Client client);
Response call123testSpecialTags(@Valid Client body);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.openapitools.model.ModelApiResponse;
import org.openapitools.model.OuterComposite;
import org.openapitools.model.User;
import org.openapitools.model.XmlItem;

import javax.ws.rs.*;
import javax.ws.rs.core.Response;
Expand All @@ -26,6 +27,14 @@
@Api(description = "the fake API")
public interface FakeApi {

@POST
@Path("/create_xml_item")
@Consumes({ "application/xml", "application/xml; charset=utf-8", "application/xml; charset=utf-16", "text/xml", "text/xml; charset=utf-8", "text/xml; charset=utf-16" })
@ApiOperation(value = "creates an XmlItem", notes = "this route creates an XmlItem", tags={ "fake", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Void.class) })
Response createXmlItem(@Valid XmlItem xmlItem);

@POST
@Path("/outer/boolean")
@Produces({ "*/*" })
Expand All @@ -40,7 +49,7 @@ public interface FakeApi {
@ApiOperation(value = "", notes = "Test serialization of object with outer number type", tags={ "fake", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Output composite", response = OuterComposite.class) })
Response fakeOuterCompositeSerialize(@Valid OuterComposite outerComposite);
Response fakeOuterCompositeSerialize(@Valid OuterComposite body);

@POST
@Path("/outer/number")
Expand All @@ -64,23 +73,23 @@ public interface FakeApi {
@ApiOperation(value = "", notes = "For this test, the body for this request much reference a schema named `File`.", tags={ "fake", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Success", response = Void.class) })
Response testBodyWithFileSchema(@Valid FileSchemaTestClass fileSchemaTestClass);
Response testBodyWithFileSchema(@Valid FileSchemaTestClass body);

@PUT
@Path("/body-with-query-params")
@Consumes({ "application/json" })
@ApiOperation(value = "", notes = "", tags={ "fake", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Success", response = Void.class) })
Response testBodyWithQueryParams(@QueryParam("query") @NotNull String query,@Valid User user);
Response testBodyWithQueryParams(@QueryParam("query") @NotNull String query,@Valid User body);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that the body parameter name changes from user to body. Likely you're not using the latest (or recent) master when creating this PR.

Please merge the latest master of the official repo into your branch and regenerate the sample again.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have used 4.3.x as the origin of my branch, are you sure I should merge master in?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Please put it on hold. I'll take another look over the weekend or next week.


@PATCH
@Consumes({ "application/json" })
@Produces({ "application/json" })
@ApiOperation(value = "To test \"client\" model", notes = "To test \"client\" model", tags={ "fake", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Client.class) })
Response testClientModel(@Valid Client client);
Response testClientModel(@Valid Client body);

@POST
@Consumes({ "application/x-www-form-urlencoded" })
Expand All @@ -98,15 +107,21 @@ public interface FakeApi {
@ApiResponses(value = {
@ApiResponse(code = 400, message = "Invalid request", response = Void.class),
@ApiResponse(code = 404, message = "Not found", response = Void.class) })
Response testEnumParameters(@HeaderParam("enum_header_string_array") @DefaultValue("new ArrayList<String>()") @ApiParam("Header parameter enum test (string array)") List<String> enumHeaderStringArray,@HeaderParam("enum_header_string") @DefaultValue("-efg") @ApiParam("Header parameter enum test (string)") String enumHeaderString,@QueryParam("enum_query_string_array") @DefaultValue("new ArrayList<String>()") @ApiParam("Query parameter enum test (string array)") List<String> enumQueryStringArray,@QueryParam("enum_query_string") @DefaultValue("-efg") @ApiParam("Query parameter enum test (string)") String enumQueryString,@QueryParam("enum_query_integer") @ApiParam("Query parameter enum test (double)") Integer enumQueryInteger,@QueryParam("enum_query_double") @ApiParam("Query parameter enum test (double)") Double enumQueryDouble,@FormParam(value = "enum_form_string_array") List<String> enumFormStringArray,@FormParam(value = "enum_form_string") String enumFormString);
Response testEnumParameters(@HeaderParam("enum_header_string_array") @DefaultValue("new ArrayList<String>()") @ApiParam("Header parameter enum test (string array)") List<String> enumHeaderStringArray,@HeaderParam("enum_header_string") @DefaultValue("-efg") @ApiParam("Header parameter enum test (string)") String enumHeaderString,@QueryParam("enum_query_string_array") @ApiParam("Query parameter enum test (string array)") List<String> enumQueryStringArray,@QueryParam("enum_query_string") @DefaultValue("-efg") @ApiParam("Query parameter enum test (string)") String enumQueryString,@QueryParam("enum_query_integer") @ApiParam("Query parameter enum test (double)") Integer enumQueryInteger,@QueryParam("enum_query_double") @ApiParam("Query parameter enum test (double)") Double enumQueryDouble,@FormParam(value = "enum_form_string_array") List<String> enumFormStringArray,@FormParam(value = "enum_form_string") String enumFormString);

@DELETE
@ApiOperation(value = "Fake endpoint to test group parameters (optional)", notes = "Fake endpoint to test group parameters (optional)", tags={ "fake", })
@ApiResponses(value = {
@ApiResponse(code = 400, message = "Someting wrong", response = Void.class) })
Response testGroupParameters(@QueryParam("required_string_group") @NotNull @ApiParam("Required String in group parameters") Integer requiredStringGroup,@HeaderParam("required_boolean_group") @NotNull @ApiParam("Required Boolean in group parameters") Boolean requiredBooleanGroup,@QueryParam("required_int64_group") @NotNull @ApiParam("Required Integer in group parameters") Long requiredInt64Group,@QueryParam("string_group") @ApiParam("String in group parameters") Integer stringGroup,@HeaderParam("boolean_group") @ApiParam("Boolean in group parameters") Boolean booleanGroup,@QueryParam("int64_group") @ApiParam("Integer in group parameters") Long int64Group);

@POST
@Path("/inline-additionalProperties")
@Consumes({ "application/json" })
@ApiOperation(value = "test inline additionalProperties", notes = "", tags={ "fake", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Void.class) })
Response testInlineAdditionalProperties(@Valid Map<String, String> requestBody);
Response testInlineAdditionalProperties(@Valid Map<String, String> param);

@GET
@Path("/jsonFormData")
Expand All @@ -116,6 +131,13 @@ public interface FakeApi {
@ApiResponse(code = 200, message = "successful operation", response = Void.class) })
Response testJsonFormData(@FormParam(value = "param") String param,@FormParam(value = "param2") String param2);

@PUT
@Path("/test-query-paramters")
@ApiOperation(value = "", notes = "To test the collection format in query parameters", tags={ "fake", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Success", response = Void.class) })
Response testQueryParameterCollectionFormat(@QueryParam("pipe") @NotNull List<String> pipe,@QueryParam("ioutil") @NotNull List<String> ioutil,@QueryParam("http") @NotNull List<String> http,@QueryParam("url") @NotNull List<String> url,@QueryParam("context") @NotNull List<String> context);

@POST
@Path("/{petId}/uploadImageWithRequiredFile")
@Consumes({ "multipart/form-data" })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ public interface FakeClassnameTestApi {
}, tags={ "fake_classname_tags 123#$%^" })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Client.class) })
Response testClassname(@Valid Client client);
Response testClassname(@Valid Client body);
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ public interface PetApi {
})
}, tags={ "pet", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Void.class),
@ApiResponse(code = 405, message = "Invalid input", response = Void.class) })
Response addPet(@Valid Pet pet);
Response addPet(@Valid Pet body);

@DELETE
@Path("/{petId}")
Expand All @@ -40,8 +41,9 @@ public interface PetApi {
})
}, tags={ "pet", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Void.class),
@ApiResponse(code = 400, message = "Invalid pet value", response = Void.class) })
Response deletePet(@PathParam("petId") @ApiParam("Pet id to delete") Long petId,@HeaderParam("api_key") String apiKey);
Response deletePet(@PathParam("petId") @ApiParam("Pet id to delete") Long petId,@HeaderParam("api_key") String apiKey);

@GET
@Path("/findByStatus")
Expand All @@ -55,7 +57,7 @@ public interface PetApi {
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Pet.class, responseContainer = "List"),
@ApiResponse(code = 400, message = "Invalid status value", response = Void.class, responseContainer = "List") })
Response findPetsByStatus(@QueryParam("status") @NotNull @DefaultValue("new ArrayList<String>()") @ApiParam("Status values that need to be considered for filter") List<String> status);
Response findPetsByStatus(@QueryParam("status") @NotNull @ApiParam("Status values that need to be considered for filter") List<String> status);

@GET
@Path("/findByTags")
Expand All @@ -69,7 +71,7 @@ public interface PetApi {
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Pet.class, responseContainer = "List"),
@ApiResponse(code = 400, message = "Invalid tag value", response = Void.class, responseContainer = "List") })
Response findPetsByTags(@QueryParam("tags") @NotNull @DefaultValue("new ArrayList<String>()") @ApiParam("Tags to filter by") List<String> tags);
Response findPetsByTags(@QueryParam("tags") @NotNull @ApiParam("Tags to filter by") List<String> tags);

@GET
@Path("/{petId}")
Expand All @@ -92,10 +94,11 @@ public interface PetApi {
})
}, tags={ "pet", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Void.class),
@ApiResponse(code = 400, message = "Invalid ID supplied", response = Void.class),
@ApiResponse(code = 404, message = "Pet not found", response = Void.class),
@ApiResponse(code = 405, message = "Validation exception", response = Void.class) })
Response updatePet(@Valid Pet pet);
Response updatePet(@Valid Pet body);

@POST
@Path("/{petId}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,5 @@ public interface StoreApi {
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Order.class),
@ApiResponse(code = 400, message = "Invalid Order", response = Void.class) })
Response placeOrder(@Valid Order order);
Response placeOrder(@Valid Order body);
}
Loading