From 5beccd12b64f3bb6d86c58a7ed9a8f2c70c62b3b Mon Sep 17 00:00:00 2001 From: Aleksandr Nekrasov Date: Tue, 17 Mar 2020 14:54:24 +0700 Subject: [PATCH] [scala][templates] java 8 dates support (#5291) * [scala][akka-http-client] java8 dates support * scala-akka readme doc updated * DateSerializers renamed * rename serializers * move date-library option to abstractScala * generators docs updated * enum defined for date libraries * Backport to scala-http-client * fix scala-akka-client date serializers * fix typo in docs * switch scala templates to java8 (jsr-310) date library by default * update scala samples with java8 date library * update scala generators docs with java8 default date library * fix scala-play-server generator cli options as only java8 dateLibrary supported * fix scalaz DateTimeCodecs template to support java8 * scalaz ci test againt java7 removed as it generate scala 2.11.8 client which is java8 based --- docs/generators/scala-akka.md | 3 +- docs/generators/scala-gatling.md | 1 + .../generators/scala-httpclient-deprecated.md | 1 + docs/generators/scala-lagom-server.md | 1 + docs/generators/scala-sttp.md | 3 +- docs/generators/scalatra.md | 1 + docs/generators/scalaz.md | 1 + .../languages/AbstractScalaCodegen.java | 58 +++++++++++++++++++ .../languages/ScalaAkkaClientCodegen.java | 6 +- .../languages/ScalaHttpClientCodegen.java | 1 + .../ScalaPlayFrameworkServerCodegen.java | 2 + .../languages/ScalaSttpClientCodegen.java | 4 -- .../scala-akka-client/apiInvoker.mustache | 16 +---- .../scala-akka-client/build.sbt.mustache | 2 + .../resources/scala-akka-client/pom.mustache | 4 ++ .../scala-akka-client/serializers.mustache | 51 ++++++++++++++++ .../resources/scalaz/dateTimeCodecs.mustache | 15 ++++- .../ScalaAkkaClientOptionsProvider.java | 2 + .../ScalaHttpClientOptionsProvider.java | 3 +- .../scalaakka/ScalaAkkaClientCodegenTest.java | 36 +++++++++++- .../ScalaHttpClientOptionsTest.java | 2 + .../codegen/scala/JavaTimeObj.scala.txt | 50 ++++++++++++++++ pom.xml | 1 - samples/client/petstore/scala-akka/build.sbt | 1 - samples/client/petstore/scala-akka/pom.xml | 6 -- .../org/openapitools/client/api/UserApi.scala | 2 +- .../openapitools/client/core/ApiInvoker.scala | 16 +---- .../client/core/Serializers.scala | 29 ++++++++++ .../org/openapitools/client/model/Order.scala | 4 +- .../org/openapitools/client/model/Order.scala | 4 +- .../client/api/DateTimeCodecs.scala | 14 ++--- .../org/openapitools/client/api/Order.scala | 4 +- .../client/petstore/scala-sttp/build.sbt | 1 - .../client/core/Serializers.scala | 24 ++++---- .../org/openapitools/client/model/Order.scala | 4 +- .../scala-finch/.openapi-generator/VERSION | 2 +- .../scala/io/swagger/client/model/Order.scala | 4 +- .../org/openapitools/server/model/Order.scala | 4 +- 38 files changed, 298 insertions(+), 85 deletions(-) create mode 100644 modules/openapi-generator/src/main/resources/scala-akka-client/serializers.mustache create mode 100644 modules/openapi-generator/src/test/resources/codegen/scala/JavaTimeObj.scala.txt create mode 100644 samples/client/petstore/scala-akka/src/main/scala/org/openapitools/client/core/Serializers.scala diff --git a/docs/generators/scala-akka.md b/docs/generators/scala-akka.md index 7ad075fd12c..ad8c5d485cf 100644 --- a/docs/generators/scala-akka.md +++ b/docs/generators/scala-akka.md @@ -7,6 +7,7 @@ sidebar_label: scala-akka | ------ | ----------- | ------ | ------- | |allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false| |apiPackage|package for generated api classes| |null| +|dateLibrary|Option. Date library to use|
**joda**
Joda (for legacy app)
**java8**
Java 8 native JSR310 (prefered for JDK 1.8+)
|java8| |ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true| |mainPackage|Top-level package name, which defines 'apiPackage', 'modelPackage', 'invokerPackage'| |org.openapitools.client| |modelPackage|package for generated models| |null| @@ -23,7 +24,7 @@ sidebar_label: scala-akka |Array|java.util.List| |ArrayList|java.util.ArrayList| |Date|java.util.Date| -|DateTime|org.joda.time.DateTime| +|DateTime|org.joda.time.*| |File|java.io.File| |HashMap|java.util.HashMap| |ListBuffer|scala.collection.mutable.ListBuffer| diff --git a/docs/generators/scala-gatling.md b/docs/generators/scala-gatling.md index be75bd085e9..0e1e748245e 100644 --- a/docs/generators/scala-gatling.md +++ b/docs/generators/scala-gatling.md @@ -7,6 +7,7 @@ sidebar_label: scala-gatling | ------ | ----------- | ------ | ------- | |allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false| |apiPackage|package for generated api classes| |null| +|dateLibrary|Option. Date library to use|
**joda**
Joda (for legacy app)
**java8**
Java 8 native JSR310 (prefered for JDK 1.8+)
|java8| |ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true| |modelPackage|package for generated models| |null| |modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |camelCase| diff --git a/docs/generators/scala-httpclient-deprecated.md b/docs/generators/scala-httpclient-deprecated.md index 574b56dee21..febeca9a690 100644 --- a/docs/generators/scala-httpclient-deprecated.md +++ b/docs/generators/scala-httpclient-deprecated.md @@ -7,6 +7,7 @@ sidebar_label: scala-httpclient-deprecated | ------ | ----------- | ------ | ------- | |allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false| |apiPackage|package for generated api classes| |null| +|dateLibrary|Option. Date library to use|
**joda**
Joda (for legacy app)
**java8**
Java 8 native JSR310 (prefered for JDK 1.8+)
|java8| |ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true| |modelPackage|package for generated models| |null| |modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |camelCase| diff --git a/docs/generators/scala-lagom-server.md b/docs/generators/scala-lagom-server.md index 407972a6f1f..99b43af7d58 100644 --- a/docs/generators/scala-lagom-server.md +++ b/docs/generators/scala-lagom-server.md @@ -7,6 +7,7 @@ sidebar_label: scala-lagom-server | ------ | ----------- | ------ | ------- | |allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false| |apiPackage|package for generated api classes| |null| +|dateLibrary|Option. Date library to use|
**joda**
Joda (for legacy app)
**java8**
Java 8 native JSR310 (prefered for JDK 1.8+)
|java8| |ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true| |modelPackage|package for generated models| |null| |modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |camelCase| diff --git a/docs/generators/scala-sttp.md b/docs/generators/scala-sttp.md index aac49c129ad..5c277bf9dcc 100644 --- a/docs/generators/scala-sttp.md +++ b/docs/generators/scala-sttp.md @@ -7,6 +7,7 @@ sidebar_label: scala-sttp | ------ | ----------- | ------ | ------- | |allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false| |apiPackage|package for generated api classes| |null| +|dateLibrary|Option. Date library to use|
**joda**
Joda (for legacy app)
**java8**
Java 8 native JSR310 (prefered for JDK 1.8+)
|java8| |ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true| |mainPackage|Top-level package name, which defines 'apiPackage', 'modelPackage', 'invokerPackage'| |org.openapitools.client| |modelPackage|package for generated models| |null| @@ -23,7 +24,7 @@ sidebar_label: scala-sttp |Array|java.util.List| |ArrayList|java.util.ArrayList| |Date|java.util.Date| -|DateTime|org.joda.time.DateTime| +|DateTime|org.joda.time.*| |File|java.io.File| |HashMap|java.util.HashMap| |ListBuffer|scala.collection.mutable.ListBuffer| diff --git a/docs/generators/scalatra.md b/docs/generators/scalatra.md index 236fa6f0efa..dcb6c8af2d7 100644 --- a/docs/generators/scalatra.md +++ b/docs/generators/scalatra.md @@ -7,6 +7,7 @@ sidebar_label: scalatra | ------ | ----------- | ------ | ------- | |allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false| |apiPackage|package for generated api classes| |null| +|dateLibrary|Option. Date library to use|
**joda**
Joda (for legacy app)
**java8**
Java 8 native JSR310 (prefered for JDK 1.8+)
|java8| |ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true| |modelPackage|package for generated models| |null| |modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |camelCase| diff --git a/docs/generators/scalaz.md b/docs/generators/scalaz.md index 1ed3bb2a176..aa2f6121ca1 100644 --- a/docs/generators/scalaz.md +++ b/docs/generators/scalaz.md @@ -7,6 +7,7 @@ sidebar_label: scalaz | ------ | ----------- | ------ | ------- | |allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false| |apiPackage|package for generated api classes| |null| +|dateLibrary|Option. Date library to use|
**joda**
Joda (for legacy app)
**java8**
Java 8 native JSR310 (prefered for JDK 1.8+)
|java8| |ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true| |modelPackage|package for generated models| |null| |modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |camelCase| diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractScalaCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractScalaCodegen.java index f866183a271..5d1a0c59087 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractScalaCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractScalaCodegen.java @@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory; import java.io.File; import java.util.*; +import static org.openapitools.codegen.languages.AbstractJavaCodegen.DATE_LIBRARY; import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.underscore; @@ -41,6 +42,19 @@ public abstract class AbstractScalaCodegen extends DefaultCodegen { protected String invokerPackage = "org.openapitools.client"; protected String sourceFolder = "src/main/scala"; protected boolean stripPackageName = true; + protected String dateLibrary = DateLibraries.java8.name(); + + protected enum DateLibraries { + java8("Java 8 native JSR310 (prefered for JDK 1.8+)"), + joda( "Joda (for legacy app)"), + legacy( "Backport to http-client (deprecated)"); + + private final String description; + + DateLibraries(String description) { + this.description = description; + } + } public AbstractScalaCodegen() { super(); @@ -131,6 +145,13 @@ public abstract class AbstractScalaCodegen extends DefaultCodegen { cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC)); cliOptions.add(new CliOption(CodegenConstants.MODEL_PROPERTY_NAMING, CodegenConstants.MODEL_PROPERTY_NAMING_DESC).defaultValue(modelPropertyNaming)); + CliOption dateLibrary = new CliOption(DATE_LIBRARY, "Option. Date library to use").defaultValue(this.dateLibrary); + Map dateOptions = new HashMap<>(); + dateOptions.put(DateLibraries.java8.name(), DateLibraries.java8.description); + dateOptions.put(DateLibraries.joda.name(), DateLibraries.joda.description); + dateLibrary.setEnum(dateOptions); + cliOptions.add(dateLibrary); + } @Override @@ -156,6 +177,43 @@ public abstract class AbstractScalaCodegen extends DefaultCodegen { setModelPropertyNaming( (String) additionalProperties.get(CodegenConstants.MODEL_PROPERTY_NAMING)); } + + if (additionalProperties.containsKey(DATE_LIBRARY)) { + this.setDateLibrary(additionalProperties.get(DATE_LIBRARY).toString(), false); + } + if (DateLibraries.java8.name().equals(dateLibrary)) { + this.importMapping.put("LocalDate", "java.time.LocalDate"); + this.importMapping.put("OffsetDateTime", "java.time.OffsetDateTime"); + this.typeMapping.put("date", "LocalDate"); + this.typeMapping.put("DateTime", "OffsetDateTime"); + additionalProperties.put("java8", "true"); + } else if (DateLibraries.joda.name().equals(dateLibrary)) { + this.importMapping.put("LocalDate", "org.joda.time.LocalDate"); + this.importMapping.put("DateTime", "org.joda.time.DateTime"); + this.importMapping.put("LocalDateTime", "org.joda.time.LocalDateTime"); + this.importMapping.put("LocalTime", "org.joda.time.LocalTime"); + this.typeMapping.put("date", "LocalDate"); + this.typeMapping.put("DateTime", "DateTime"); + additionalProperties.put("joda", "true"); + } + } + + public void setDateLibrary(String dateLibrary, boolean withLegacy) { + if (withLegacy && dateLibrary.equals(DateLibraries.legacy.name())) { + this.dateLibrary = dateLibrary; + return; + } + for ( DateLibraries dateLib : DateLibraries.values()) { + if (dateLib.name().equals(dateLibrary)) { + this.dateLibrary = dateLibrary; + return; + } + } + throw new IllegalArgumentException("Invalid dateLibrary. Must be 'java8' or 'joda'"); + } + + public String getDateLibrary() { + return this.dateLibrary; } public void setModelPropertyNaming(String naming) { diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaAkkaClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaAkkaClientCodegen.java index 01940e73088..8f1bdde8c63 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaAkkaClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaAkkaClientCodegen.java @@ -35,6 +35,7 @@ import java.io.StringWriter; import java.io.Writer; import java.util.*; +import static org.openapitools.codegen.languages.AbstractJavaCodegen.DATE_LIBRARY; import static org.openapitools.codegen.utils.StringUtils.camelize; public class ScalaAkkaClientCodegen extends AbstractScalaCodegen implements CodegenConfig { @@ -49,8 +50,6 @@ public class ScalaAkkaClientCodegen extends AbstractScalaCodegen implements Code protected boolean registerNonStandardStatusCodes = true; protected boolean renderJavadoc = true; protected boolean removeOAuthSecurities = true; - // protected boolean stripPackageName = false; - @SuppressWarnings("hiding") protected Logger LOGGER = LoggerFactory.getLogger(ScalaAkkaClientCodegen.class); @@ -121,8 +120,6 @@ public class ScalaAkkaClientCodegen extends AbstractScalaCodegen implements Code importMapping.remove("Set"); importMapping.remove("Map"); - importMapping.put("DateTime", "org.joda.time.DateTime"); - typeMapping = new HashMap<>(); typeMapping.put("array", "Seq"); typeMapping.put("set", "Set"); @@ -172,6 +169,7 @@ public class ScalaAkkaClientCodegen extends AbstractScalaCodegen implements Code supportingFiles.add(new SupportingFile("apiSettings.mustache", invokerFolder, "ApiSettings.scala")); final String apiFolder = (sourceFolder + File.separator + apiPackage).replace(".", File.separator); supportingFiles.add(new SupportingFile("enumsSerializers.mustache", apiFolder, "EnumsSerializers.scala")); + supportingFiles.add(new SupportingFile("serializers.mustache", invokerFolder, "Serializers.scala")); } @Override diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaHttpClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaHttpClientCodegen.java index 58c5255def7..27f0991bf7f 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaHttpClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaHttpClientCodegen.java @@ -131,6 +131,7 @@ public class ScalaHttpClientCodegen extends AbstractScalaCodegen implements Code importMapping.remove("Set"); importMapping.remove("Map"); + setDateLibrary("legacy",true); importMapping.put("Date", "java.util.Date"); typeMapping = new HashMap(); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaPlayFrameworkServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaPlayFrameworkServerCodegen.java index d0a72315677..4c1da136a2e 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaPlayFrameworkServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaPlayFrameworkServerCodegen.java @@ -35,6 +35,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import static org.apache.commons.lang3.StringUtils.rightPad; +import static org.openapitools.codegen.languages.AbstractJavaCodegen.DATE_LIBRARY; import static org.openapitools.codegen.utils.OnceLogger.once; import static org.openapitools.codegen.utils.StringUtils.camelize; @@ -102,6 +103,7 @@ public class ScalaPlayFrameworkServerCodegen extends AbstractScalaCodegen implem importMapping.remove("BigDecimal"); importMapping.put("TemporaryFile", "play.api.libs.Files.TemporaryFile"); + cliOptions.removeIf(opt -> DATE_LIBRARY.equals(opt.getOpt())); cliOptions.add(new CliOption(ROUTES_FILE_NAME, "Name of the routes file to generate.").defaultValue(routesFileName)); cliOptions.add(new CliOption(BASE_PACKAGE, "Base package in which supporting classes are generated.").defaultValue(basePackage)); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaSttpClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaSttpClientCodegen.java index 2c1441c2bde..dd1e8846860 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaSttpClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaSttpClientCodegen.java @@ -53,10 +53,6 @@ public class ScalaSttpClientCodegen extends ScalaAkkaClientCodegen implements Co additionalProperties.put("modelPackage", modelPackage); } - if (!additionalProperties.containsKey("java8")) { - additionalProperties.put("joda", "true"); - } - supportingFiles.clear(); supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); supportingFiles.add(new SupportingFile("build.sbt.mustache", "", "build.sbt")); diff --git a/modules/openapi-generator/src/main/resources/scala-akka-client/apiInvoker.mustache b/modules/openapi-generator/src/main/resources/scala-akka-client/apiInvoker.mustache index d27cec1e405..83957a81896 100644 --- a/modules/openapi-generator/src/main/resources/scala-akka-client/apiInvoker.mustache +++ b/modules/openapi-generator/src/main/resources/scala-akka-client/apiInvoker.mustache @@ -15,9 +15,6 @@ import akka.stream.ActorMaterializer import akka.stream.scaladsl.Source import akka.util.{ ByteString, Timeout } import de.heikoseeberger.akkahttpjson4s.Json4sSupport -import org.joda.time.DateTime -import org.joda.time.format.ISODateTimeFormat -import org.json4s.JsonAST.JString import org.json4s._ import org.json4s.jackson.JsonMethods._ import org.json4s.jackson.Serialization @@ -29,10 +26,10 @@ import scala.reflect.ClassTag object ApiInvoker { def apply()(implicit system: ActorSystem): ApiInvoker = - apply(DefaultFormats + DateTimeSerializer) + apply(DefaultFormats ++ Serializers.all) def apply(serializers: Iterable[Serializer[_]])(implicit system: ActorSystem): ApiInvoker = - apply(DefaultFormats + DateTimeSerializer ++ serializers) + apply(DefaultFormats ++ Serializers.all ++ serializers) def apply(formats: Formats)(implicit system: ActorSystem): ApiInvoker = new ApiInvoker(formats) @@ -67,15 +64,6 @@ object ApiInvoker { def toAkkaHttpMethod: HttpMethod = HttpMethods.getForKey(method.value).getOrElse(HttpMethods.GET) } - case object DateTimeSerializer extends CustomSerializer[DateTime](_ => ( { - case JString(s) => - ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(s) - }, { - case d: DateTime => - JString(ISODateTimeFormat.dateTime().print(d)) - }) - ) - } trait UnitJSONSupport { diff --git a/modules/openapi-generator/src/main/resources/scala-akka-client/build.sbt.mustache b/modules/openapi-generator/src/main/resources/scala-akka-client/build.sbt.mustache index a806f3694b6..4a6c13d55fb 100644 --- a/modules/openapi-generator/src/main/resources/scala-akka-client/build.sbt.mustache +++ b/modules/openapi-generator/src/main/resources/scala-akka-client/build.sbt.mustache @@ -8,7 +8,9 @@ libraryDependencies ++= Seq( "com.typesafe.akka" %% "akka-actor" % "2.5.21", "com.typesafe.akka" %% "akka-stream" % "2.5.21", "com.typesafe.akka" %% "akka-http" % "10.1.7", +{{#joda}} "joda-time" % "joda-time" % "2.10.1", +{{/joda}} "org.json4s" %% "json4s-jackson" % "3.6.5", "org.json4s" %% "json4s-ext" % "3.6.5", "de.heikoseeberger" %% "akka-http-json4s" % "1.25.2", diff --git a/modules/openapi-generator/src/main/resources/scala-akka-client/pom.mustache b/modules/openapi-generator/src/main/resources/scala-akka-client/pom.mustache index 65e18d49da2..9162fce7a25 100644 --- a/modules/openapi-generator/src/main/resources/scala-akka-client/pom.mustache +++ b/modules/openapi-generator/src/main/resources/scala-akka-client/pom.mustache @@ -20,7 +20,9 @@ 3.2.11 2.5.21 10.1.7 +{{#joda}} 2.10.1 +{{/joda}} 1.3.3 1.25.2 4.13 @@ -36,11 +38,13 @@ ${scala.version} provided +{{#joda}} joda-time joda-time ${joda.time.version} +{{/joda}} com.typesafe config diff --git a/modules/openapi-generator/src/main/resources/scala-akka-client/serializers.mustache b/modules/openapi-generator/src/main/resources/scala-akka-client/serializers.mustache new file mode 100644 index 00000000000..ea3d00b54e7 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/scala-akka-client/serializers.mustache @@ -0,0 +1,51 @@ +package {{invokerPackage}} + +{{#java8}} +import java.time.{LocalDate, LocalDateTime, OffsetDateTime, ZoneId} +import java.time.format.DateTimeFormatter +{{/java8}} +{{#joda}} +import org.joda.time.format.ISODateTimeFormat +import org.joda.time.{LocalDate, DateTime} +{{/joda}} +import org.json4s.{Serializer, CustomSerializer, JNull} +import org.json4s.JsonAST.JString + +import scala.util.Try + +object Serializers { + +{{#java8}} + case object DateTimeSerializer extends CustomSerializer[OffsetDateTime]( _ => ( { + case JString(s) => + Try(OffsetDateTime.parse(s, DateTimeFormatter.ISO_OFFSET_DATE_TIME)) orElse + Try(LocalDateTime.parse(s).atZone(ZoneId.systemDefault()).toOffsetDateTime) getOrElse null + }, { + case d: OffsetDateTime => + JString(d.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)) + })) + + case object LocalDateSerializer extends CustomSerializer[LocalDate]( _ => ( { + case JString(s) => LocalDate.parse(s) + }, { + JString(d.format(DateTimeFormatter.ISO_LOCAL_DATE)) + })) +{{/java8}} +{{#joda}} + case object DateTimeSerializer extends CustomSerializer[DateTime](_ => ( { + case JString(s) => + ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(s) + }, { + case d: DateTime => JString(ISODateTimeFormat.dateTime().print(d)) + })) + + case object LocalDateSerializer extends CustomSerializer[LocalDate]( _ => ( { + case JString(s) => ISODateTimeFormat.localDateParser().parseLocalDate(s) + }, { + case d: LocalDate => JString(ISODateTimeFormat.date().print(d)) + })) +{{/joda}} + + def all: Seq[Serializer[_]] = Seq[Serializer[_]]() :+ DateTimeSerializer :+ LocalDateSerializer + +} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/scalaz/dateTimeCodecs.mustache b/modules/openapi-generator/src/main/resources/scalaz/dateTimeCodecs.mustache index fa73adb562e..178b02754b5 100644 --- a/modules/openapi-generator/src/main/resources/scalaz/dateTimeCodecs.mustache +++ b/modules/openapi-generator/src/main/resources/scalaz/dateTimeCodecs.mustache @@ -7,13 +7,26 @@ import argonaut.DecodeJson._ import org.http4s._ import org.http4s.{EntityDecoder, EntityEncoder} import org.http4s.argonaut._ - +{{#joda}} import org.joda.time.DateTime +{{/joda}} +{{#java8}} +import java.time.OffsetDateTime +{{/java8}} object DateTimeCodecs { +{{#joda}} implicit def dateTimeEncodeJson: EncodeJson[DateTime] = EncodeJson[DateTime](dt => StringEncodeJson(dt.toString)) implicit def dateTimeDecodeJson: DecodeJson[DateTime] = DecodeJson.of[String].map(DateTime.parse(_)) setName "org.joda.time.DateTime" +{{/joda}} +{{#java8}} + implicit def dateTimeEncodeJson: EncodeJson[OffsetDateTime] = + EncodeJson[OffsetDateTime](dt => StringEncodeJson(dt.toString)) + + implicit def dateTimeDecodeJson: DecodeJson[OffsetDateTime] = + DecodeJson.of[String].map(OffsetDateTime.parse(_)) setName "java.time.OffsetDateTime" +{{/java8}} } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/ScalaAkkaClientOptionsProvider.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/ScalaAkkaClientOptionsProvider.java index 36f82c8e2c0..f9ac4d5ee3b 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/ScalaAkkaClientOptionsProvider.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/ScalaAkkaClientOptionsProvider.java @@ -33,6 +33,7 @@ public class ScalaAkkaClientOptionsProvider implements OptionsProvider { public static final String PREPEND_FORM_OR_BODY_PARAMETERS_VALUE = "true"; public static final String MAIN_PACKAGE_VALUE = "net.test"; public static final String MODEL_PROPERTY_NAMING = "camelCase"; + public static final String DATE_LIBRARY = "joda"; @Override @@ -53,6 +54,7 @@ public class ScalaAkkaClientOptionsProvider implements OptionsProvider { .put(CodegenConstants.PREPEND_FORM_OR_BODY_PARAMETERS, PREPEND_FORM_OR_BODY_PARAMETERS_VALUE) .put("mainPackage", MAIN_PACKAGE_VALUE) .put(CodegenConstants.MODEL_PROPERTY_NAMING, MODEL_PROPERTY_NAMING) + .put("dateLibrary", DATE_LIBRARY) .build(); } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/ScalaHttpClientOptionsProvider.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/ScalaHttpClientOptionsProvider.java index 6c41744f23f..c128ea1bba7 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/ScalaHttpClientOptionsProvider.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/ScalaHttpClientOptionsProvider.java @@ -32,7 +32,7 @@ public class ScalaHttpClientOptionsProvider implements OptionsProvider { public static final String MODEL_PROPERTY_NAMING = "PascalCase"; public static final String ALLOW_UNICODE_IDENTIFIERS_VALUE = "false"; public static final String PREPEND_FORM_OR_BODY_PARAMETERS_VALUE = "true"; - + public static final String DATE_LIBRARY = "joda"; @Override public String getLanguage() { @@ -51,6 +51,7 @@ public class ScalaHttpClientOptionsProvider implements OptionsProvider { .put(CodegenConstants.SOURCE_FOLDER, SOURCE_FOLDER_VALUE) .put(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, ALLOW_UNICODE_IDENTIFIERS_VALUE) .put(CodegenConstants.PREPEND_FORM_OR_BODY_PARAMETERS, PREPEND_FORM_OR_BODY_PARAMETERS_VALUE) + .put("dateLibrary", DATE_LIBRARY) .build(); } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/scalaakka/ScalaAkkaClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/scalaakka/ScalaAkkaClientCodegenTest.java index 51069186354..34e536bdf90 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/scalaakka/ScalaAkkaClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/scalaakka/ScalaAkkaClientCodegenTest.java @@ -335,10 +335,11 @@ public class ScalaAkkaClientCodegenTest { Assert.assertEquals(Sets.intersection(cm.imports, Sets.newHashSet("Map", "Children")).size(), 1); } - @Test(description = "validate codegen output") + @Test(description = "validate codegen joda output") public void codeGenerationTest() throws Exception { Map properties = new HashMap<>(); properties.put("mainPackage", "hello.world"); + properties.put("dateLibrary", "joda"); File output = Files.createTempDirectory("test").toFile(); output.deleteOnExit(); @@ -356,7 +357,7 @@ public class ScalaAkkaClientCodegenTest { generator.opts(clientOptInput).generate(); Map generatedFiles = generator.getFiles(); - Assert.assertEquals(generatedFiles.size(), 13); + Assert.assertEquals(generatedFiles.size(), 14); final String someObjFilename = new File(output, "src/main/scala/hello/world/model/SomeObj.scala").getAbsolutePath().replace("\\", "/"); Assert.assertEquals( @@ -364,6 +365,37 @@ public class ScalaAkkaClientCodegenTest { Resources.toString(Resources.getResource("codegen/scala/SomeObj.scala.txt"), StandardCharsets.UTF_8)); } + @Test(description = "validate codegen java8 output") + public void codeGenerationJava8Test() throws Exception { + Map properties = new HashMap<>(); + properties.put("mainPackage", "hello.world"); + properties.put("dateLibrary", "java8"); + + File output = Files.createTempDirectory("test").toFile(); + output.deleteOnExit(); + + final DefaultCodegen codegen = new ScalaAkkaClientCodegen(); + + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName(codegen.getName()) + .setAdditionalProperties(properties) + .setInputSpec("src/test/resources/3_0/scala_reserved_words.yaml") + .setOutputDir(output.getAbsolutePath().replace("\\", "/")); + + final ClientOptInput clientOptInput = configurator.toClientOptInput(); + MockDefaultGenerator generator = new MockDefaultGenerator(); + generator.opts(clientOptInput).generate(); + + Map generatedFiles = generator.getFiles(); + Assert.assertEquals(generatedFiles.size(), 14); + + final String someObjFilename = new File(output, "src/main/scala/hello/world/model/SomeObj.scala").getAbsolutePath().replace("\\", "/"); + Assert.assertEquals( + generatedFiles.get(someObjFilename), + Resources.toString(Resources.getResource("codegen/scala/JavaTimeObj.scala.txt"), StandardCharsets.UTF_8)); + } + + @Test(description = "strip model name") public void stripModelNameTest() throws Exception { final Schema model = new Schema() diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/scalahttpclient/ScalaHttpClientOptionsTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/scalahttpclient/ScalaHttpClientOptionsTest.java index 3f31758c12d..a70da4206bc 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/scalahttpclient/ScalaHttpClientOptionsTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/scalahttpclient/ScalaHttpClientOptionsTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; public class ScalaHttpClientOptionsTest extends AbstractOptionsTest { + private ScalaHttpClientCodegen clientCodegen = mock(ScalaHttpClientCodegen.class, mockSettings); public ScalaHttpClientOptionsTest() { @@ -46,5 +47,6 @@ public class ScalaHttpClientOptionsTest extends AbstractOptionsTest { verify(clientCodegen).setModelPropertyNaming(ScalaHttpClientOptionsProvider.MODEL_PROPERTY_NAMING); verify(clientCodegen).setSourceFolder(ScalaHttpClientOptionsProvider.SOURCE_FOLDER_VALUE); verify(clientCodegen).setPrependFormOrBodyParameters(Boolean.valueOf(ScalaHttpClientOptionsProvider.PREPEND_FORM_OR_BODY_PARAMETERS_VALUE)); + verify(clientCodegen).setDateLibrary(ScalaHttpClientOptionsProvider.DATE_LIBRARY,false); } } diff --git a/modules/openapi-generator/src/test/resources/codegen/scala/JavaTimeObj.scala.txt b/modules/openapi-generator/src/test/resources/codegen/scala/JavaTimeObj.scala.txt new file mode 100644 index 00000000000..bd26dd8e6a4 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/codegen/scala/JavaTimeObj.scala.txt @@ -0,0 +1,50 @@ +/** + * ping some object + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +package hello.world.model + +import java.time.OffsetDateTime +import hello.world.core.ApiModel + +case class SomeObj ( + `type`: Option[SomeObjEnums.`Type`] = None, + id: Long, + name: Option[String] = None, + `val`: Option[String] = None, + `var`: Option[String] = None, + `class`: Option[String] = None, + `trait`: Option[String] = None, + `object`: Option[String] = None, + `try`: String, + `catch`: String, + `finally`: String, + `def`: Option[String] = None, + `for`: Option[String] = None, + `implicit`: Option[String] = None, + `match`: Option[String] = None, + `case`: Option[String] = None, + `import`: Option[String] = None, + `lazy`: String, + `private`: Option[String] = None, + `type`: Option[String] = None, + foobar: Boolean, + createdAt: OffsetDateTime +) extends ApiModel + +object SomeObjEnums { + + type `Type` = `Type`.Value + object `Type` extends Enumeration { + val SomeObjIdentifier = Value("SomeObjIdentifier") + } + +} + diff --git a/pom.xml b/pom.xml index eb094907ada..7c42edcc5bb 100644 --- a/pom.xml +++ b/pom.xml @@ -1388,7 +1388,6 @@ samples/client/petstore/dart-jaguar/openapi samples/client/petstore/dart-jaguar/flutter_petstore/openapi samples/client/petstore/scala-httpclient - samples/client/petstore/scalaz samples/client/petstore/java/feign samples/client/petstore/java/jersey1 samples/client/petstore/java/jersey2 diff --git a/samples/client/petstore/scala-akka/build.sbt b/samples/client/petstore/scala-akka/build.sbt index 150b1f75bcf..d19487cbe0d 100644 --- a/samples/client/petstore/scala-akka/build.sbt +++ b/samples/client/petstore/scala-akka/build.sbt @@ -8,7 +8,6 @@ libraryDependencies ++= Seq( "com.typesafe.akka" %% "akka-actor" % "2.5.21", "com.typesafe.akka" %% "akka-stream" % "2.5.21", "com.typesafe.akka" %% "akka-http" % "10.1.7", - "joda-time" % "joda-time" % "2.10.1", "org.json4s" %% "json4s-jackson" % "3.6.5", "org.json4s" %% "json4s-ext" % "3.6.5", "de.heikoseeberger" %% "akka-http-json4s" % "1.25.2", diff --git a/samples/client/petstore/scala-akka/pom.xml b/samples/client/petstore/scala-akka/pom.xml index 33f89264546..bd865860a90 100644 --- a/samples/client/petstore/scala-akka/pom.xml +++ b/samples/client/petstore/scala-akka/pom.xml @@ -20,7 +20,6 @@ 3.2.11 2.5.21 10.1.7 - 2.10.1 1.3.3 1.25.2 4.13 @@ -36,11 +35,6 @@ ${scala.version} provided - - joda-time - joda-time - ${joda.time.version} - com.typesafe config diff --git a/samples/client/petstore/scala-akka/src/main/scala/org/openapitools/client/api/UserApi.scala b/samples/client/petstore/scala-akka/src/main/scala/org/openapitools/client/api/UserApi.scala index 7a784fd0298..54809067608 100644 --- a/samples/client/petstore/scala-akka/src/main/scala/org/openapitools/client/api/UserApi.scala +++ b/samples/client/petstore/scala-akka/src/main/scala/org/openapitools/client/api/UserApi.scala @@ -131,7 +131,7 @@ class UserApi(baseUrl: String) { object LoginUserHeaders { def setCookie(r: ApiReturnWithHeaders) = r.getStringHeader("Set-Cookie") def xRateLimit(r: ApiReturnWithHeaders) = r.getIntHeader("X-Rate-Limit") - def xExpiresAfter(r: ApiReturnWithHeaders) = r.getDateTimeHeader("X-Expires-After") + def xExpiresAfter(r: ApiReturnWithHeaders) = r.getOffsetDateTimeHeader("X-Expires-After") } /** diff --git a/samples/client/petstore/scala-akka/src/main/scala/org/openapitools/client/core/ApiInvoker.scala b/samples/client/petstore/scala-akka/src/main/scala/org/openapitools/client/core/ApiInvoker.scala index 70c1246c979..3e6c1dbeb44 100644 --- a/samples/client/petstore/scala-akka/src/main/scala/org/openapitools/client/core/ApiInvoker.scala +++ b/samples/client/petstore/scala-akka/src/main/scala/org/openapitools/client/core/ApiInvoker.scala @@ -25,9 +25,6 @@ import akka.stream.ActorMaterializer import akka.stream.scaladsl.Source import akka.util.{ ByteString, Timeout } import de.heikoseeberger.akkahttpjson4s.Json4sSupport -import org.joda.time.DateTime -import org.joda.time.format.ISODateTimeFormat -import org.json4s.JsonAST.JString import org.json4s._ import org.json4s.jackson.JsonMethods._ import org.json4s.jackson.Serialization @@ -39,10 +36,10 @@ import scala.reflect.ClassTag object ApiInvoker { def apply()(implicit system: ActorSystem): ApiInvoker = - apply(DefaultFormats + DateTimeSerializer) + apply(DefaultFormats ++ Serializers.all) def apply(serializers: Iterable[Serializer[_]])(implicit system: ActorSystem): ApiInvoker = - apply(DefaultFormats + DateTimeSerializer ++ serializers) + apply(DefaultFormats ++ Serializers.all ++ serializers) def apply(formats: Formats)(implicit system: ActorSystem): ApiInvoker = new ApiInvoker(formats) @@ -77,15 +74,6 @@ object ApiInvoker { def toAkkaHttpMethod: HttpMethod = HttpMethods.getForKey(method.value).getOrElse(HttpMethods.GET) } - case object DateTimeSerializer extends CustomSerializer[DateTime](_ => ( { - case JString(s) => - ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(s) - }, { - case d: DateTime => - JString(ISODateTimeFormat.dateTime().print(d)) - }) - ) - } trait UnitJSONSupport { diff --git a/samples/client/petstore/scala-akka/src/main/scala/org/openapitools/client/core/Serializers.scala b/samples/client/petstore/scala-akka/src/main/scala/org/openapitools/client/core/Serializers.scala new file mode 100644 index 00000000000..bb3ac5290ce --- /dev/null +++ b/samples/client/petstore/scala-akka/src/main/scala/org/openapitools/client/core/Serializers.scala @@ -0,0 +1,29 @@ +package org.openapitools.client.core + +import java.time.{LocalDate, LocalDateTime, OffsetDateTime, ZoneId} +import java.time.format.DateTimeFormatter +import org.json4s.{Serializer, CustomSerializer, JNull} +import org.json4s.JsonAST.JString + +import scala.util.Try + +object Serializers { + + case object DateTimeSerializer extends CustomSerializer[OffsetDateTime]( _ => ( { + case JString(s) => + Try(OffsetDateTime.parse(s, DateTimeFormatter.ISO_OFFSET_DATE_TIME)) orElse + Try(LocalDateTime.parse(s).atZone(ZoneId.systemDefault()).toOffsetDateTime) getOrElse null + }, { + case d: OffsetDateTime => + JString(d.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)) + })) + + case object LocalDateSerializer extends CustomSerializer[LocalDate]( _ => ( { + case JString(s) => LocalDate.parse(s) + }, { + JString(d.format(DateTimeFormatter.ISO_LOCAL_DATE)) + })) + + def all: Seq[Serializer[_]] = Seq[Serializer[_]]() :+ DateTimeSerializer :+ LocalDateSerializer + +} \ No newline at end of file diff --git a/samples/client/petstore/scala-akka/src/main/scala/org/openapitools/client/model/Order.scala b/samples/client/petstore/scala-akka/src/main/scala/org/openapitools/client/model/Order.scala index 6a9fdc141f0..95204d35e5d 100644 --- a/samples/client/petstore/scala-akka/src/main/scala/org/openapitools/client/model/Order.scala +++ b/samples/client/petstore/scala-akka/src/main/scala/org/openapitools/client/model/Order.scala @@ -11,14 +11,14 @@ */ package org.openapitools.client.model -import org.joda.time.DateTime +import java.time.OffsetDateTime import org.openapitools.client.core.ApiModel case class Order ( id: Option[Long] = None, petId: Option[Long] = None, quantity: Option[Int] = None, - shipDate: Option[DateTime] = None, + shipDate: Option[OffsetDateTime] = None, /* Order Status */ status: Option[OrderEnums.Status] = None, complete: Option[Boolean] = None diff --git a/samples/client/petstore/scala-gatling/src/gatling/scala/org/openapitools/client/model/Order.scala b/samples/client/petstore/scala-gatling/src/gatling/scala/org/openapitools/client/model/Order.scala index ba6967f0e17..526d8d6b07f 100644 --- a/samples/client/petstore/scala-gatling/src/gatling/scala/org/openapitools/client/model/Order.scala +++ b/samples/client/petstore/scala-gatling/src/gatling/scala/org/openapitools/client/model/Order.scala @@ -1,13 +1,13 @@ package org.openapitools.client.model -import java.util.Date +import java.time.OffsetDateTime case class Order ( _id: Option[Long], _petId: Option[Long], _quantity: Option[Integer], - _shipDate: Option[Date], + _shipDate: Option[OffsetDateTime], /* Order Status */ _status: Option[String], _complete: Option[Boolean] diff --git a/samples/client/petstore/scalaz/src/main/scala/org/openapitools/client/api/DateTimeCodecs.scala b/samples/client/petstore/scalaz/src/main/scala/org/openapitools/client/api/DateTimeCodecs.scala index f71d95a3728..890338a8ffb 100644 --- a/samples/client/petstore/scalaz/src/main/scala/org/openapitools/client/api/DateTimeCodecs.scala +++ b/samples/client/petstore/scalaz/src/main/scala/org/openapitools/client/api/DateTimeCodecs.scala @@ -4,16 +4,12 @@ import argonaut._ import argonaut.EncodeJson._ import argonaut.DecodeJson._ -import org.http4s._ -import org.http4s.{EntityDecoder, EntityEncoder} -import org.http4s.argonaut._ - -import org.joda.time.DateTime +import java.time.OffsetDateTime object DateTimeCodecs { - implicit def dateTimeEncodeJson: EncodeJson[DateTime] = - EncodeJson[DateTime](dt => StringEncodeJson(dt.toString)) + implicit def dateTimeEncodeJson: EncodeJson[OffsetDateTime] = + EncodeJson[OffsetDateTime](dt => StringEncodeJson(dt.toString)) - implicit def dateTimeDecodeJson: DecodeJson[DateTime] = - DecodeJson.of[String].map(DateTime.parse(_)) setName "org.joda.time.DateTime" + implicit def dateTimeDecodeJson: DecodeJson[OffsetDateTime] = + DecodeJson.of[String].map(OffsetDateTime.parse(_)) setName "java.time.OffsetDateTime" } diff --git a/samples/client/petstore/scalaz/src/main/scala/org/openapitools/client/api/Order.scala b/samples/client/petstore/scalaz/src/main/scala/org/openapitools/client/api/Order.scala index 67e3cd4318a..0af3f367c61 100644 --- a/samples/client/petstore/scalaz/src/main/scala/org/openapitools/client/api/Order.scala +++ b/samples/client/petstore/scalaz/src/main/scala/org/openapitools/client/api/Order.scala @@ -8,7 +8,7 @@ import org.http4s.{EntityDecoder, EntityEncoder} import org.http4s.argonaut._ import org.joda.time.DateTime -import org.joda.time.DateTime +import java.time.OffsetDateTime import Order._ @@ -16,7 +16,7 @@ case class Order ( id: Option[Long], petId: Option[Long], quantity: Option[Integer], -shipDate: Option[DateTime], +shipDate: Option[OffsetDateTime], /* Order Status */ status: Option[Status], complete: Option[Boolean]) diff --git a/samples/openapi3/client/petstore/scala-sttp/build.sbt b/samples/openapi3/client/petstore/scala-sttp/build.sbt index 610244cee60..68b09b1d6dd 100644 --- a/samples/openapi3/client/petstore/scala-sttp/build.sbt +++ b/samples/openapi3/client/petstore/scala-sttp/build.sbt @@ -9,7 +9,6 @@ crossScalaVersions := Seq(scalaVersion.value, "2.12.10", "2.11.12") libraryDependencies ++= Seq( "com.softwaremill.sttp.client" %% "core" % "2.0.0", "com.softwaremill.sttp.client" %% "json4s" % "2.0.0", - "joda-time" % "joda-time" % "2.10.1", "org.json4s" %% "json4s-jackson" % "3.6.7", // test dependencies "org.scalatest" %% "scalatest" % "3.0.8" % Test, diff --git a/samples/openapi3/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/core/Serializers.scala b/samples/openapi3/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/core/Serializers.scala index 80188ba5e6a..dbd13545c73 100644 --- a/samples/openapi3/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/core/Serializers.scala +++ b/samples/openapi3/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/core/Serializers.scala @@ -1,27 +1,29 @@ package org.openapitools.client.core -import org.joda.time.DateTime -import org.joda.time.format.ISODateTimeFormat +import java.time.{LocalDate, LocalDateTime, OffsetDateTime, ZoneId} +import java.time.format.DateTimeFormatter +import scala.util.Try import org.json4s.{Serializer, CustomSerializer, JNull} import org.json4s.JsonAST.JString object Serializers { - case object DateTimeSerializer extends CustomSerializer[DateTime](_ => ( { + case object DateTimeSerializer extends CustomSerializer[OffsetDateTime](_ => ( { case JString(s) => - ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(s) + Try(OffsetDateTime.parse(s, DateTimeFormatter.ISO_OFFSET_DATE_TIME)) orElse + Try(LocalDateTime.parse(s).atZone(ZoneId.systemDefault()).toOffsetDateTime) getOrElse (null) case JNull => null }, { - case d: org.joda.time.DateTime => - JString(ISODateTimeFormat.dateTime().print(d)) - }) - ) + case d: OffsetDateTime => + JString(d.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)) + })) - case object LocalDateSerializer extends CustomSerializer[org.joda.time.LocalDate](_ => ( { - case JString(s) => org.joda.time.format.DateTimeFormat.forPattern("yyyy-MM-dd").parseLocalDate(s) + case object LocalDateSerializer extends CustomSerializer[LocalDate]( _ => ( { + case JString(s) => LocalDate.parse(s) case JNull => null }, { - case d: org.joda.time.LocalDate => JString(d.toString("yyyy-MM-dd")) + case d: LocalDate => + JString(d.format(DateTimeFormatter.ISO_LOCAL_DATE)) })) def all: Seq[Serializer[_]] = Seq[Serializer[_]]() :+ LocalDateSerializer :+ DateTimeSerializer diff --git a/samples/openapi3/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/model/Order.scala b/samples/openapi3/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/model/Order.scala index b8f11b0b3c3..baa0c0cb14a 100644 --- a/samples/openapi3/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/model/Order.scala +++ b/samples/openapi3/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/model/Order.scala @@ -11,7 +11,7 @@ */ package org.openapitools.client.model -import org.joda.time.DateTime +import java.time.OffsetDateTime import org.openapitools.client.core.ApiModel /** @@ -22,7 +22,7 @@ case class Order( id: Option[Long] = None, petId: Option[Long] = None, quantity: Option[Int] = None, - shipDate: Option[DateTime] = None, + shipDate: Option[OffsetDateTime] = None, /* Order Status */ status: Option[OrderEnums.Status] = None, complete: Option[Boolean] = None diff --git a/samples/server/petstore/scala-finch/.openapi-generator/VERSION b/samples/server/petstore/scala-finch/.openapi-generator/VERSION index afa63656064..bfbf77eb7fa 100644 --- a/samples/server/petstore/scala-finch/.openapi-generator/VERSION +++ b/samples/server/petstore/scala-finch/.openapi-generator/VERSION @@ -1 +1 @@ -4.0.0-SNAPSHOT \ No newline at end of file +4.3.0-SNAPSHOT \ No newline at end of file diff --git a/samples/server/petstore/scala-lagom-server/src/main/scala/io/swagger/client/model/Order.scala b/samples/server/petstore/scala-lagom-server/src/main/scala/io/swagger/client/model/Order.scala index 1f86d47b25b..b788db2ab51 100644 --- a/samples/server/petstore/scala-lagom-server/src/main/scala/io/swagger/client/model/Order.scala +++ b/samples/server/petstore/scala-lagom-server/src/main/scala/io/swagger/client/model/Order.scala @@ -12,13 +12,13 @@ package io.swagger.client.model import play.api.libs.json._ -import org.joda.time.DateTime +import java.time.OffsetDateTime case class Order ( id: Option[Long], petId: Option[Long], quantity: Option[Int], - shipDate: Option[DateTime], + shipDate: Option[OffsetDateTime], status: Option[OrderStatusEnum.OrderStatusEnum], complete: Option[Boolean] ) diff --git a/samples/server/petstore/scalatra/src/main/scala/org/openapitools/server/model/Order.scala b/samples/server/petstore/scalatra/src/main/scala/org/openapitools/server/model/Order.scala index 809f722db47..b011c782967 100644 --- a/samples/server/petstore/scalatra/src/main/scala/org/openapitools/server/model/Order.scala +++ b/samples/server/petstore/scalatra/src/main/scala/org/openapitools/server/model/Order.scala @@ -10,7 +10,7 @@ */ package org.openapitools.server.model -import org.joda.time.DateTime +import java.time.OffsetDateTime case class Order( id: Option[Long], @@ -19,7 +19,7 @@ case class Order( quantity: Option[Int], - shipDate: Option[DateTime], + shipDate: Option[OffsetDateTime], /* Order Status */ status: Option[String],