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

[#19921] Add RFC 3339 compatible Jackson module for java.time types #19925

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,8 @@ public void processOpts() {
additionalProperties.remove(SERIALIZATION_LIBRARY_GSON);
additionalProperties.remove(SERIALIZATION_LIBRARY_JSONB);
supportingFiles.add(new SupportingFile("RFC3339DateFormat.mustache", invokerFolder, "RFC3339DateFormat.java"));
supportingFiles.add(new SupportingFile("RFC3339InstantDeserializer.mustache", invokerFolder, "RFC3339InstantDeserializer.java"));
supportingFiles.add(new SupportingFile("RFC3339JavaTimeModule.mustache", invokerFolder, "RFC3339JavaTimeModule.java"));
beikov marked this conversation as resolved.
Show resolved Hide resolved
break;
case SERIALIZATION_LIBRARY_GSON:
additionalProperties.put(SERIALIZATION_LIBRARY_GSON, "true");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
{{>licenseInfo}}
package {{invokerPackage}};

import java.io.IOException;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
import java.util.function.BiFunction;
import java.util.function.Function;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeFeature;
import com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer;

{{>generatedAnnotation}}
public class RFC3339InstantDeserializer<T extends Temporal> extends InstantDeserializer<T> {

private final static boolean DEFAULT_NORMALIZE_ZONE_ID = JavaTimeFeature.NORMALIZE_DESERIALIZED_ZONE_ID.enabledByDefault();
private final static boolean DEFAULT_ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS
= JavaTimeFeature.ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS.enabledByDefault();

public static final RFC3339InstantDeserializer<Instant> INSTANT = new RFC3339InstantDeserializer<>(
Instant.class, DateTimeFormatter.ISO_INSTANT,
Instant::from,
a -> Instant.ofEpochMilli( a.value ),
a -> Instant.ofEpochSecond( a.integer, a.fraction ),
null,
true, // yes, replace zero offset with Z
DEFAULT_NORMALIZE_ZONE_ID,
DEFAULT_ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS
);

public static final RFC3339InstantDeserializer<OffsetDateTime> OFFSET_DATE_TIME = new RFC3339InstantDeserializer<>(
OffsetDateTime.class, DateTimeFormatter.ISO_OFFSET_DATE_TIME,
OffsetDateTime::from,
a -> OffsetDateTime.ofInstant( Instant.ofEpochMilli( a.value ), a.zoneId ),
a -> OffsetDateTime.ofInstant( Instant.ofEpochSecond( a.integer, a.fraction ), a.zoneId ),
(d, z) -> ( d.isEqual( OffsetDateTime.MIN ) || d.isEqual( OffsetDateTime.MAX ) ?
d :
d.withOffsetSameInstant( z.getRules().getOffset( d.toLocalDateTime() ) ) ),
true, // yes, replace zero offset with Z
DEFAULT_NORMALIZE_ZONE_ID,
DEFAULT_ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS
);

public static final RFC3339InstantDeserializer<ZonedDateTime> ZONED_DATE_TIME = new RFC3339InstantDeserializer<>(
ZonedDateTime.class, DateTimeFormatter.ISO_ZONED_DATE_TIME,
ZonedDateTime::from,
a -> ZonedDateTime.ofInstant( Instant.ofEpochMilli( a.value ), a.zoneId ),
a -> ZonedDateTime.ofInstant( Instant.ofEpochSecond( a.integer, a.fraction ), a.zoneId ),
ZonedDateTime::withZoneSameInstant,
false, // keep zero offset and Z separate since zones explicitly supported
DEFAULT_NORMALIZE_ZONE_ID,
DEFAULT_ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS
);

protected RFC3339InstantDeserializer(
Class<T> supportedType,
DateTimeFormatter formatter,
Function<TemporalAccessor, T> parsedToValue,
Function<FromIntegerArguments, T> fromMilliseconds,
Function<FromDecimalArguments, T> fromNanoseconds,
BiFunction<T, ZoneId, T> adjust,
boolean replaceZeroOffsetAsZ,
boolean normalizeZoneId,
boolean readNumericStringsAsTimestamp) {
super(
beikov marked this conversation as resolved.
Show resolved Hide resolved
supportedType,
formatter,
parsedToValue,
fromMilliseconds,
fromNanoseconds,
adjust,
replaceZeroOffsetAsZ,
normalizeZoneId,
readNumericStringsAsTimestamp
);
}

@Override
protected T _fromString(JsonParser p, DeserializationContext ctxt, String string0) throws IOException {
return super._fromString(p, ctxt, string0.replace( ' ', 'T' ));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{{>licenseInfo}}
package {{invokerPackage}};

import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;

import com.fasterxml.jackson.databind.module.SimpleModule;

{{>generatedAnnotation}}
public class RFC3339JavaTimeModule extends SimpleModule {

public RFC3339JavaTimeModule() {
super("RFC3339JavaTimeModule");

addDeserializer(Instant.class, RFC3339InstantDeserializer.INSTANT);
addDeserializer(OffsetDateTime.class, RFC3339InstantDeserializer.OFFSET_DATE_TIME);
addDeserializer(ZonedDateTime.class, RFC3339InstantDeserializer.ZONED_DATE_TIME);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
{{#openApiNullable}}
objectMapper.registerModule(new JsonNullableModule());
{{/openApiNullable}}
objectMapper.registerModule(new RFC3339JavaTimeModule());
objectMapper.setDateFormat(ApiClient.buildDefaultDateFormat());

dateFormat = ApiClient.buildDefaultDateFormat();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ public class ApiClient {
objectMapper.registerModule(new JodaModule());
{{/joda}}
objectMapper.registerModule(new JavaTimeModule());
Copy link
Member

Choose a reason for hiding this comment

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

The JavaTimeModule can already deserialize RFC3339 datetimes

objectMapper.registerModule(new RFC3339JavaTimeModule());
beikov marked this conversation as resolved.
Show resolved Hide resolved
{{#openApiNullable}}
JsonNullableModule jnm = new JsonNullableModule();
objectMapper.registerModule(jnm);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class JSON implements ContextResolver<ObjectMapper> {
{{#openApiNullable}}
.addModule(new JsonNullableModule())
{{/openApiNullable}}
.addModule(new RFC3339JavaTimeModule())
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class JSON implements ContextResolver<ObjectMapper> {
{{#openApiNullable}}
.addModule(new JsonNullableModule())
{{/openApiNullable}}
.addModule(new RFC3339JavaTimeModule())
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ public class ApiClient {
{{#openApiNullable}}
mapper.registerModule(new JsonNullableModule());
{{/openApiNullable}}
mapper.registerModule(new RFC3339JavaTimeModule());
return mapper;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ public void testJdkHttpClient() {

List<File> files = new DefaultGenerator().opts(configurator.toClientOptInput()).generate();

assertThat(files).hasSize(32);
assertThat(files).hasSize(34);
validateJavaSourceFiles(files);
assertThat(output.resolve("src/main/java/xyz/abcdef/api/DefaultApi.java")).content().contains(
"public class DefaultApi",
Expand Down Expand Up @@ -606,7 +606,7 @@ public void testJdkHttpAsyncClient() {

List<File> files = new DefaultGenerator().opts(configurator.toClientOptInput()).generate();

assertThat(files).hasSize(35);
assertThat(files).hasSize(37);

validateJavaSourceFiles(files);
assertThat(output.resolve("src/main/java/xyz/abcdef/api/PingApi.java")).content().contains(
Expand Down Expand Up @@ -1427,7 +1427,7 @@ public void testNativeClientWhiteSpacePathParamEncoding() {
List<File> files = new DefaultGenerator().opts(configurator.toClientOptInput()).generate();

validateJavaSourceFiles(files);
assertThat(files).hasSize(35);
assertThat(files).hasSize(37);
TestUtils.assertFileContains(output.resolve("src/main/java/xyz/abcdef/ApiClient.java"),
"public static String urlEncode(String s) { return URLEncoder.encode(s,"
+ " UTF_8).replaceAll(\"\\\\+\", \"%20\"); }"
Expand All @@ -1450,7 +1450,7 @@ public void testNativeClientExplodedQueryParamObject() {
List<File> files = new DefaultGenerator().opts(configurator.toClientOptInput()).generate();

validateJavaSourceFiles(files);
assertThat(files).hasSize(38);
assertThat(files).hasSize(40);
assertThat(output.resolve("src/main/java/xyz/abcdef/api/DefaultApi.java")).content()
.contains(
"localVarQueryParams.addAll(ApiClient.parameterToPairs(\"since\", queryObject.getSince()));",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void testApacheHttpClientExplodedQueryParamObject() throws IOException {
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(clientOptInput).generate();

Assert.assertEquals(files.size(), 42);
Assert.assertEquals(files.size(), 44);
validateJavaSourceFiles(files);

TestUtils.assertFileContains(Paths.get(output + "/src/main/java/xyz/abcdef/api/DefaultApi.java"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.11.0-SNAPSHOT
7.10.0-SNAPSHOT
2 changes: 1 addition & 1 deletion samples/client/echo_api/csharp-restsharp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This C# SDK is automatically generated by the [OpenAPI Generator](https://openap

- API version: 0.1.0
- SDK version: 1.0.0
- Generator version: 7.11.0-SNAPSHOT
- Generator version: 7.10.0-SNAPSHOT
- Build package: org.openapitools.codegen.languages.CSharpClientCodegen

<a id="frameworks-supported"></a>
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.11.0-SNAPSHOT
7.10.0-SNAPSHOT
2 changes: 1 addition & 1 deletion samples/client/echo_api/go-external-refs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This API client was generated by the [OpenAPI Generator](https://openapi-generat

- API version: 0.1.0
- Package version: 1.0.0
- Generator version: 7.11.0-SNAPSHOT
- Generator version: 7.10.0-SNAPSHOT
- Build package: org.openapitools.codegen.languages.GoClientCodegen

## Installation
Expand Down
2 changes: 1 addition & 1 deletion samples/client/echo_api/go/.openapi-generator/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.11.0-SNAPSHOT
7.10.0-SNAPSHOT
2 changes: 1 addition & 1 deletion samples/client/echo_api/go/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This API client was generated by the [OpenAPI Generator](https://openapi-generat

- API version: 0.1.0
- Package version: 1.0.0
- Generator version: 7.11.0-SNAPSHOT
- Generator version: 7.10.0-SNAPSHOT
- Build package: org.openapitools.codegen.languages.GoClientCodegen

## Installation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ src/main/java/org/openapitools/client/Configuration.java
src/main/java/org/openapitools/client/JavaTimeFormatter.java
src/main/java/org/openapitools/client/Pair.java
src/main/java/org/openapitools/client/RFC3339DateFormat.java
src/main/java/org/openapitools/client/RFC3339InstantDeserializer.java
src/main/java/org/openapitools/client/RFC3339JavaTimeModule.java
src/main/java/org/openapitools/client/ServerConfiguration.java
src/main/java/org/openapitools/client/ServerVariable.java
src/main/java/org/openapitools/client/StringUtil.java
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.11.0-SNAPSHOT
7.10.0-SNAPSHOT
2 changes: 1 addition & 1 deletion samples/client/echo_api/java/apache-httpclient/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Echo Server API

- API version: 0.1.0

- Generator version: 7.11.0-SNAPSHOT
- Generator version: 7.10.0-SNAPSHOT

Echo Server API

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
import org.openapitools.client.auth.HttpBasicAuth;
import org.openapitools.client.auth.HttpBearerAuth;

@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.11.0-SNAPSHOT")
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.10.0-SNAPSHOT")
public class ApiClient extends JavaTimeFormatter {
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
private Map<String, String> defaultCookieMap = new HashMap<String, String>();
Expand Down Expand Up @@ -122,6 +122,7 @@ public ApiClient(CloseableHttpClient httpClient) {
objectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
objectMapper.registerModule(new JavaTimeModule());
objectMapper.registerModule(new JsonNullableModule());
objectMapper.registerModule(new RFC3339JavaTimeModule());
objectMapper.setDateFormat(ApiClient.buildDefaultDateFormat());

dateFormat = ApiClient.buildDefaultDateFormat();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import java.util.Map;
import java.util.List;

@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.11.0-SNAPSHOT")
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.10.0-SNAPSHOT")
public class ApiException extends Exception {
private static final long serialVersionUID = 1L;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import java.util.Collections;
import java.util.Map;

@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.11.0-SNAPSHOT")
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.10.0-SNAPSHOT")
public abstract class BaseApi {

protected ApiClient apiClient;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

package org.openapitools.client;

@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.11.0-SNAPSHOT")
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.10.0-SNAPSHOT")
public class Configuration {
public static final String VERSION = "0.1.0";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* Class that add parsing/formatting support for Java 8+ {@code OffsetDateTime} class.
* It's generated for java clients when {@code AbstractJavaCodegen#dateLibrary} specified as {@code java8}.
*/
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.11.0-SNAPSHOT")
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.10.0-SNAPSHOT")
public class JavaTimeFormatter {

private DateTimeFormatter offsetDateTimeFormatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

package org.openapitools.client;

@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.11.0-SNAPSHOT")
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.10.0-SNAPSHOT")
public class Pair {
private String name = "";
private String value = "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import java.util.GregorianCalendar;
import java.util.TimeZone;

@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.11.0-SNAPSHOT")
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.10.0-SNAPSHOT")
public class RFC3339DateFormat extends DateFormat {
private static final long serialVersionUID = 1L;
private static final TimeZone TIMEZONE_Z = TimeZone.getTimeZone("UTC");
Expand Down
Loading
Loading