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 471ce4d08dd0..68aa5e7b6196 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 @@ -674,9 +674,10 @@ public void processOpts() { importMapping.put("LocalDate", "java.time.LocalDate"); typeMapping.put("time-local","LocalTime"); importMapping.put("LocalTime", "java.time.LocalTime"); + typeMapping.put("date-time-local", "LocalDateTime"); + importMapping.put("LocalDateTime", "java.time.LocalDateTime"); if ("java8-localdatetime".equals(dateLibrary)) { typeMapping.put("DateTime", "LocalDateTime"); - importMapping.put("LocalDateTime", "java.time.LocalDateTime"); } else { typeMapping.put("DateTime", "OffsetDateTime"); importMapping.put("OffsetDateTime", "java.time.OffsetDateTime"); @@ -1450,6 +1451,13 @@ public String toDefaultValue(CodegenProperty cp, Schema schema) { } } return null; + } else if (ModelUtils.isDateTimeLocalSchema(schema)) { + if (schema.getDefault() != null) { + if ("java8".equals(getDateLibrary())) { + return String.format(Locale.ROOT, "LocalDateTime.parse(\"%s\")", String.valueOf(schema.getDefault())); + } + } + return null; } else if (ModelUtils.isStringSchema(schema)) { if (schema.getDefault() != null) { String _default; @@ -1536,6 +1544,10 @@ public String toDefaultValue(CodegenProperty cp, Schema schema) { if("java8".equals(getDateLibrary())) { defaultPropertyExpression = String.format(Locale.ROOT, "java.time.LocalTime.parse(\"%s\")", value.asText()); } + } else if(ModelUtils.isDateTimeLocalSchema(propertySchema)) { + if("java8".equals(getDateLibrary())) { + defaultPropertyExpression = String.format(Locale.ROOT, "java.time.LocalDateTime.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 46df3cf0d53b..88346d9046f7 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 @@ -715,6 +715,12 @@ public static boolean isDateTimeSchema(Schema schema) { && SchemaTypeUtil.DATE_TIME_FORMAT.equals(schema.getFormat())); } + public static boolean isDateTimeLocalSchema(Schema schema) { + // format: date-time-local, see https://spec.openapis.org/registry/format/date-time-local.html + return (SchemaTypeUtil.STRING_TYPE.equals(getType(schema)) + && "date-time-local".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 fa9bbb3375ce..775f50a37b65 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 @@ -537,6 +537,15 @@ public void toDefaultValueDateTimeLegacyTest() { // dateLibrary <> java8 Assert.assertEquals(defaultValue, "10:15:30"); + + // Test default value for date-time-local format + StringSchema dateTimeLocalSchema = new StringSchema(); + dateTimeLocalSchema.setFormat("date-time-local"); + dateTimeLocalSchema.setDefault(LocalDateTime.parse("2007-12-03T10:15:30")); + defaultValue = codegen.toDefaultValue(dateTimeLocalSchema); + + // dateLibrary <> java8 + Assert.assertEquals(defaultValue, "2007-12-03T10:15:30"); } @Test @@ -606,6 +615,13 @@ public void toDefaultValueTest() { timeLocalSchema.setDefault("10:15:30"); defaultValue = codegen.toDefaultValue(codegen.fromProperty("", timeLocalSchema), timeLocalSchema); Assert.assertEquals(defaultValue, "LocalTime.parse(\"10:15:30\")"); + + // Test default value for date-time-local format + StringSchema dateTimeLocalSchema = new StringSchema(); + dateTimeLocalSchema.setFormat("date-time-local"); + 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 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 b5d0467b75fa..313551ea65de 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 @@ -412,6 +412,35 @@ public void generateLocalTimeForTimeLocalFormat() throws IOException { .assertProperty("feedingTime").withType("LocalTime"); } + @Test + public void generateLocalDateTimeForDateTimeLocalFormat() 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.LocalDateTime") + .assertProperty("adoptionDate").withType("LocalDateTime"); + } + @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 cfc47f06afe8..330cbc8598b4 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 @@ -105,4 +105,8 @@ components: feedingTime: type: string format: time-local - default: '10:15:30' \ No newline at end of file + default: '10:15:30' + adoptionDate: + type: string + format: date-time-local + default: '2007-12-03T10:15:30' \ 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 0885482c7410..540d84f91e52 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 @@ -6,6 +6,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import java.math.BigDecimal; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.LocalTime; import java.time.OffsetDateTime; import org.springframework.format.annotation.DateTimeFormat; @@ -43,6 +44,8 @@ public class Pet { private LocalTime feedingTime = LocalTime.parse("10:15:30"); + private LocalDateTime adoptionDate = LocalDateTime.parse("2007-12-03T10:15:30"); + public Pet() { super(); } @@ -201,6 +204,27 @@ public void setFeedingTime(LocalTime feedingTime) { this.feedingTime = feedingTime; } + public Pet adoptionDate(LocalDateTime adoptionDate) { + this.adoptionDate = adoptionDate; + return this; + } + + /** + * Get adoptionDate + * @return adoptionDate + */ + @Valid + @Schema(name = "adoptionDate", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("adoptionDate") + public LocalDateTime getAdoptionDate() { + return adoptionDate; + } + + @JsonProperty("adoptionDate") + public void setAdoptionDate(LocalDateTime adoptionDate) { + this.adoptionDate = adoptionDate; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -216,12 +240,13 @@ public boolean equals(Object o) { Objects.equals(this.price, pet.price) && Objects.equals(this.lastFeed, pet.lastFeed) && Objects.equals(this.dateOfBirth, pet.dateOfBirth) && - Objects.equals(this.feedingTime, pet.feedingTime); + Objects.equals(this.feedingTime, pet.feedingTime) && + Objects.equals(this.adoptionDate, pet.adoptionDate); } @Override public int hashCode() { - return Objects.hash(atType, age, happy, price, lastFeed, dateOfBirth, feedingTime); + return Objects.hash(atType, age, happy, price, lastFeed, dateOfBirth, feedingTime, adoptionDate); } @Override @@ -235,6 +260,7 @@ public String toString() { sb.append(" lastFeed: ").append(toIndentedString(lastFeed)).append("\n"); 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("}"); 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 0885482c7410..540d84f91e52 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 @@ -6,6 +6,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import java.math.BigDecimal; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.LocalTime; import java.time.OffsetDateTime; import org.springframework.format.annotation.DateTimeFormat; @@ -43,6 +44,8 @@ public class Pet { private LocalTime feedingTime = LocalTime.parse("10:15:30"); + private LocalDateTime adoptionDate = LocalDateTime.parse("2007-12-03T10:15:30"); + public Pet() { super(); } @@ -201,6 +204,27 @@ public void setFeedingTime(LocalTime feedingTime) { this.feedingTime = feedingTime; } + public Pet adoptionDate(LocalDateTime adoptionDate) { + this.adoptionDate = adoptionDate; + return this; + } + + /** + * Get adoptionDate + * @return adoptionDate + */ + @Valid + @Schema(name = "adoptionDate", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("adoptionDate") + public LocalDateTime getAdoptionDate() { + return adoptionDate; + } + + @JsonProperty("adoptionDate") + public void setAdoptionDate(LocalDateTime adoptionDate) { + this.adoptionDate = adoptionDate; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -216,12 +240,13 @@ public boolean equals(Object o) { Objects.equals(this.price, pet.price) && Objects.equals(this.lastFeed, pet.lastFeed) && Objects.equals(this.dateOfBirth, pet.dateOfBirth) && - Objects.equals(this.feedingTime, pet.feedingTime); + Objects.equals(this.feedingTime, pet.feedingTime) && + Objects.equals(this.adoptionDate, pet.adoptionDate); } @Override public int hashCode() { - return Objects.hash(atType, age, happy, price, lastFeed, dateOfBirth, feedingTime); + return Objects.hash(atType, age, happy, price, lastFeed, dateOfBirth, feedingTime, adoptionDate); } @Override @@ -235,6 +260,7 @@ public String toString() { sb.append(" lastFeed: ").append(toIndentedString(lastFeed)).append("\n"); 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("}"); return sb.toString(); }