diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java index 68aa5e7b6196..fcb1db46222a 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java @@ -676,6 +676,8 @@ public void processOpts() { importMapping.put("LocalTime", "java.time.LocalTime"); typeMapping.put("date-time-local", "LocalDateTime"); importMapping.put("LocalDateTime", "java.time.LocalDateTime"); + typeMapping.put("duration", "Duration"); + importMapping.put("Duration", "java.time.Duration"); if ("java8-localdatetime".equals(dateLibrary)) { typeMapping.put("DateTime", "LocalDateTime"); } else { @@ -1458,6 +1460,13 @@ public String toDefaultValue(CodegenProperty cp, Schema schema) { } } return null; + } else if (ModelUtils.isDurationSchema(schema)) { + if (schema.getDefault() != null) { + if ("java8".equals(getDateLibrary())) { + return String.format(Locale.ROOT, "Duration.parse(\"%s\")", schema.getDefault()); + } + } + return null; } else if (ModelUtils.isStringSchema(schema)) { if (schema.getDefault() != null) { String _default; @@ -1548,6 +1557,10 @@ public String toDefaultValue(CodegenProperty cp, Schema schema) { if("java8".equals(getDateLibrary())) { defaultPropertyExpression = String.format(Locale.ROOT, "java.time.LocalDateTime.parse(\"%s\")", value.asText()); } + } else if(ModelUtils.isDurationSchema(propertySchema)) { + if("java8".equals(getDateLibrary())) { + defaultPropertyExpression = String.format(Locale.ROOT, "java.time.Duration.parse(\"%s\")", value.asText()); + } } else if(ModelUtils.isUUIDSchema(propertySchema)) { defaultPropertyExpression = "java.util.UUID.fromString(\"" + value.asText() + "\")"; } else if(ModelUtils.isStringSchema(propertySchema)) { diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java index 88346d9046f7..814985cb7ecb 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java @@ -721,6 +721,12 @@ public static boolean isDateTimeLocalSchema(Schema schema) { && "date-time-local".equals(schema.getFormat())); } + public static boolean isDurationSchema(Schema schema) { + // format: duration, see https://spec.openapis.org/registry/format/duration.html + return (SchemaTypeUtil.STRING_TYPE.equals(getType(schema)) + && "duration".equals(schema.getFormat())); + } + public static boolean isTimeLocalSchema(Schema schema) { // format: time-local, see https://spec.openapis.org/registry/format/time-local.html return (SchemaTypeUtil.STRING_TYPE.equals(getType(schema)) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/AbstractJavaCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/AbstractJavaCodegenTest.java index 775f50a37b65..8e122c302ed7 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/AbstractJavaCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/AbstractJavaCodegenTest.java @@ -546,6 +546,15 @@ public void toDefaultValueDateTimeLegacyTest() { // dateLibrary <> java8 Assert.assertEquals(defaultValue, "2007-12-03T10:15:30"); + + // Test default value for duration format + StringSchema durationSchema = new StringSchema(); + durationSchema.setFormat("duration"); + durationSchema.setDefault(Duration.parse("PT20.345S")); + defaultValue = codegen.toDefaultValue(durationSchema); + + // dateLibrary <> java8 + Assert.assertEquals(defaultValue, "PT20.345S"); } @Test @@ -622,6 +631,13 @@ public void toDefaultValueTest() { dateTimeLocalSchema.setDefault("2007-12-03T10:15:30"); defaultValue = codegen.toDefaultValue(codegen.fromProperty("", dateTimeLocalSchema), dateTimeLocalSchema); Assert.assertEquals(defaultValue, "LocalDateTime.parse(\"2007-12-03T10:15:30\")"); + + // Test default value for duration format + StringSchema durationSchema = new StringSchema(); + durationSchema.setFormat("duration"); + durationSchema.setDefault("PT20.345S"); + defaultValue = codegen.toDefaultValue(codegen.fromProperty("", durationSchema), durationSchema); + Assert.assertEquals(defaultValue, "Duration.parse(\"PT20.345S\")"); } @Test diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java index 313551ea65de..ccf492c4389e 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java @@ -441,6 +441,35 @@ public void generateLocalDateTimeForDateTimeLocalFormat() throws IOException { .assertProperty("adoptionDate").withType("LocalDateTime"); } + @Test + public void generateDurationForDurationFormat() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + String outputPath = output.getAbsolutePath().replace('\\', '/'); + + OpenAPI openAPI = new OpenAPIParser() + .readLocation("src/test/resources/3_0/spring/date-time-parameter-types-for-testing.yml", null, new ParseOptions()).getOpenAPI(); + + SpringCodegen codegen = new SpringCodegen(); + codegen.setOutputDir(output.getAbsolutePath()); + + ClientOptInput input = new ClientOptInput(); + input.openAPI(openAPI); + input.config(codegen); + + DefaultGenerator generator = new DefaultGenerator(); + generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false"); + generator.setGenerateMetadata(false); + generator.opts(input).generate(); + + JavaFileAssert.assertThat(Paths.get(outputPath + "/src/main/java/org/openapitools/model/Pet.java")) + .hasImports("java.time.Duration") + .assertProperty("tripDuration").withType("Duration"); + } + @Test public void interfaceDefaultImplDisableWithResponseWrapper() { final SpringCodegen codegen = new SpringCodegen(); diff --git a/modules/openapi-generator/src/test/resources/3_0/spring/date-time-parameter-types-for-testing.yml b/modules/openapi-generator/src/test/resources/3_0/spring/date-time-parameter-types-for-testing.yml index 330cbc8598b4..e943e43571ce 100644 --- a/modules/openapi-generator/src/test/resources/3_0/spring/date-time-parameter-types-for-testing.yml +++ b/modules/openapi-generator/src/test/resources/3_0/spring/date-time-parameter-types-for-testing.yml @@ -109,4 +109,8 @@ components: adoptionDate: type: string format: date-time-local - default: '2007-12-03T10:15:30' \ No newline at end of file + default: '2007-12-03T10:15:30' + tripDuration: + type: string + format: duration + default: 'PT10H15M30S' \ No newline at end of file diff --git a/samples/client/petstore/spring-cloud-date-time/src/main/java/org/openapitools/model/Pet.java b/samples/client/petstore/spring-cloud-date-time/src/main/java/org/openapitools/model/Pet.java index 540d84f91e52..1305140a3c2d 100644 --- a/samples/client/petstore/spring-cloud-date-time/src/main/java/org/openapitools/model/Pet.java +++ b/samples/client/petstore/spring-cloud-date-time/src/main/java/org/openapitools/model/Pet.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonCreator; import java.math.BigDecimal; +import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -46,6 +47,8 @@ public class Pet { private LocalDateTime adoptionDate = LocalDateTime.parse("2007-12-03T10:15:30"); + private Duration tripDuration = Duration.parse("PT10H15M30S"); + public Pet() { super(); } @@ -225,6 +228,27 @@ public void setAdoptionDate(LocalDateTime adoptionDate) { this.adoptionDate = adoptionDate; } + public Pet tripDuration(Duration tripDuration) { + this.tripDuration = tripDuration; + return this; + } + + /** + * Get tripDuration + * @return tripDuration + */ + @Valid + @Schema(name = "tripDuration", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("tripDuration") + public Duration getTripDuration() { + return tripDuration; + } + + @JsonProperty("tripDuration") + public void setTripDuration(Duration tripDuration) { + this.tripDuration = tripDuration; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -241,12 +265,13 @@ public boolean equals(Object o) { Objects.equals(this.lastFeed, pet.lastFeed) && Objects.equals(this.dateOfBirth, pet.dateOfBirth) && Objects.equals(this.feedingTime, pet.feedingTime) && - Objects.equals(this.adoptionDate, pet.adoptionDate); + Objects.equals(this.adoptionDate, pet.adoptionDate) && + Objects.equals(this.tripDuration, pet.tripDuration); } @Override public int hashCode() { - return Objects.hash(atType, age, happy, price, lastFeed, dateOfBirth, feedingTime, adoptionDate); + return Objects.hash(atType, age, happy, price, lastFeed, dateOfBirth, feedingTime, adoptionDate, tripDuration); } @Override @@ -261,6 +286,7 @@ public String toString() { sb.append(" dateOfBirth: ").append(toIndentedString(dateOfBirth)).append("\n"); sb.append(" feedingTime: ").append(toIndentedString(feedingTime)).append("\n"); sb.append(" adoptionDate: ").append(toIndentedString(adoptionDate)).append("\n"); + sb.append(" tripDuration: ").append(toIndentedString(tripDuration)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/samples/openapi3/client/petstore/spring-cloud-date-time/src/main/java/org/openapitools/model/Pet.java b/samples/openapi3/client/petstore/spring-cloud-date-time/src/main/java/org/openapitools/model/Pet.java index 540d84f91e52..1305140a3c2d 100644 --- a/samples/openapi3/client/petstore/spring-cloud-date-time/src/main/java/org/openapitools/model/Pet.java +++ b/samples/openapi3/client/petstore/spring-cloud-date-time/src/main/java/org/openapitools/model/Pet.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonCreator; import java.math.BigDecimal; +import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -46,6 +47,8 @@ public class Pet { private LocalDateTime adoptionDate = LocalDateTime.parse("2007-12-03T10:15:30"); + private Duration tripDuration = Duration.parse("PT10H15M30S"); + public Pet() { super(); } @@ -225,6 +228,27 @@ public void setAdoptionDate(LocalDateTime adoptionDate) { this.adoptionDate = adoptionDate; } + public Pet tripDuration(Duration tripDuration) { + this.tripDuration = tripDuration; + return this; + } + + /** + * Get tripDuration + * @return tripDuration + */ + @Valid + @Schema(name = "tripDuration", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("tripDuration") + public Duration getTripDuration() { + return tripDuration; + } + + @JsonProperty("tripDuration") + public void setTripDuration(Duration tripDuration) { + this.tripDuration = tripDuration; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -241,12 +265,13 @@ public boolean equals(Object o) { Objects.equals(this.lastFeed, pet.lastFeed) && Objects.equals(this.dateOfBirth, pet.dateOfBirth) && Objects.equals(this.feedingTime, pet.feedingTime) && - Objects.equals(this.adoptionDate, pet.adoptionDate); + Objects.equals(this.adoptionDate, pet.adoptionDate) && + Objects.equals(this.tripDuration, pet.tripDuration); } @Override public int hashCode() { - return Objects.hash(atType, age, happy, price, lastFeed, dateOfBirth, feedingTime, adoptionDate); + return Objects.hash(atType, age, happy, price, lastFeed, dateOfBirth, feedingTime, adoptionDate, tripDuration); } @Override @@ -261,6 +286,7 @@ public String toString() { sb.append(" dateOfBirth: ").append(toIndentedString(dateOfBirth)).append("\n"); sb.append(" feedingTime: ").append(toIndentedString(feedingTime)).append("\n"); sb.append(" adoptionDate: ").append(toIndentedString(adoptionDate)).append("\n"); + sb.append(" tripDuration: ").append(toIndentedString(tripDuration)).append("\n"); sb.append("}"); return sb.toString(); }