From 00ee2d5b4f1e847d8e272c79f66230aa30cb11d6 Mon Sep 17 00:00:00 2001 From: Pamela Dragosh Date: Thu, 18 Feb 2021 09:57:23 -0600 Subject: Add more java.time adapters The time extensions require these adapters for anyone using our gson adapter to serialize/deserialize the DecisionRequest. Issue-ID: POLICY-2810 Change-Id: I64a7e4a5a256c77bd67dab867664e41b61cd0050 Signed-off-by: Pamela Dragosh --- .../policy/common/gson/GsonMessageBodyHandler.java | 12 +++- .../policy/common/gson/LocalDateTypeAdapter.java | 68 ++++++++++++++++++++ .../common/gson/OffsetDateTimeTypeAdapter.java | 68 ++++++++++++++++++++ .../policy/common/gson/OffsetTimeTypeAdapter.java | 68 ++++++++++++++++++++ .../policy/common/gson/ZoneOffsetTypeAdapter.java | 57 +++++++++++++++++ .../common/gson/LocalDateTypeAdapterTest.java | 73 ++++++++++++++++++++++ .../common/gson/OffsetDateTimeAdapterTest.java | 72 +++++++++++++++++++++ .../common/gson/OffsetTimeTypeAdapterTest.java | 72 +++++++++++++++++++++ .../common/gson/ZoneOffsetTypeAdapterTest.java | 72 +++++++++++++++++++++ 9 files changed, 560 insertions(+), 2 deletions(-) create mode 100644 gson/src/main/java/org/onap/policy/common/gson/LocalDateTypeAdapter.java create mode 100644 gson/src/main/java/org/onap/policy/common/gson/OffsetDateTimeTypeAdapter.java create mode 100644 gson/src/main/java/org/onap/policy/common/gson/OffsetTimeTypeAdapter.java create mode 100644 gson/src/main/java/org/onap/policy/common/gson/ZoneOffsetTypeAdapter.java create mode 100644 gson/src/test/java/org/onap/policy/common/gson/LocalDateTypeAdapterTest.java create mode 100644 gson/src/test/java/org/onap/policy/common/gson/OffsetDateTimeAdapterTest.java create mode 100644 gson/src/test/java/org/onap/policy/common/gson/OffsetTimeTypeAdapterTest.java create mode 100644 gson/src/test/java/org/onap/policy/common/gson/ZoneOffsetTypeAdapterTest.java (limited to 'gson') diff --git a/gson/src/main/java/org/onap/policy/common/gson/GsonMessageBodyHandler.java b/gson/src/main/java/org/onap/policy/common/gson/GsonMessageBodyHandler.java index d6e36b39..df3def3c 100644 --- a/gson/src/main/java/org/onap/policy/common/gson/GsonMessageBodyHandler.java +++ b/gson/src/main/java/org/onap/policy/common/gson/GsonMessageBodyHandler.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,11 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.time.Instant; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.ZoneOffset; import java.time.ZonedDateTime; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; @@ -91,7 +95,11 @@ public class GsonMessageBodyHandler implements MessageBodyReader, Messag return builder.disableHtmlEscaping().registerTypeAdapterFactory(new MapDoubleAdapterFactory()) .registerTypeAdapter(Instant.class, new InstantTypeAdapter()) .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter()) - .registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeTypeAdapter()); + .registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeTypeAdapter()) + .registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeTypeAdapter()) + .registerTypeAdapter(OffsetTime.class, new OffsetTimeTypeAdapter()) + .registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter()) + .registerTypeAdapter(ZoneOffset.class, new ZoneOffsetTypeAdapter()); } @Override diff --git a/gson/src/main/java/org/onap/policy/common/gson/LocalDateTypeAdapter.java b/gson/src/main/java/org/onap/policy/common/gson/LocalDateTypeAdapter.java new file mode 100644 index 00000000..8e33e464 --- /dev/null +++ b/gson/src/main/java/org/onap/policy/common/gson/LocalDateTypeAdapter.java @@ -0,0 +1,68 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.gson; + +import com.google.gson.JsonParseException; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; + +public class LocalDateTypeAdapter extends TypeAdapter { + private DateTimeFormatter formatter; + + public LocalDateTypeAdapter() { + this(DateTimeFormatter.ISO_LOCAL_DATE); + } + + public LocalDateTypeAdapter(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + @Override + public LocalDate read(JsonReader in) throws IOException { + try { + if (in.peek() == JsonToken.NULL) { + in.nextNull(); + return null; + } else { + return LocalDate.parse(in.nextString(), formatter); + } + + } catch (DateTimeParseException e) { + throw new JsonParseException("invalid date", e); + } + } + + @Override + public void write(JsonWriter out, LocalDate value) throws IOException { + if (value == null) { + out.nullValue(); + } else { + String text = value.format(formatter); + out.value(text); + } + } +} diff --git a/gson/src/main/java/org/onap/policy/common/gson/OffsetDateTimeTypeAdapter.java b/gson/src/main/java/org/onap/policy/common/gson/OffsetDateTimeTypeAdapter.java new file mode 100644 index 00000000..faf5ffd1 --- /dev/null +++ b/gson/src/main/java/org/onap/policy/common/gson/OffsetDateTimeTypeAdapter.java @@ -0,0 +1,68 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.gson; + +import com.google.gson.JsonParseException; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; + +public class OffsetDateTimeTypeAdapter extends TypeAdapter { + private DateTimeFormatter formatter; + + public OffsetDateTimeTypeAdapter() { + this(DateTimeFormatter.ISO_OFFSET_DATE_TIME); + } + + public OffsetDateTimeTypeAdapter(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + @Override + public OffsetDateTime read(JsonReader in) throws IOException { + try { + if (in.peek() == JsonToken.NULL) { + in.nextNull(); + return null; + } else { + return OffsetDateTime.parse(in.nextString(), formatter); + } + + } catch (DateTimeParseException e) { + throw new JsonParseException("invalid date", e); + } + } + + @Override + public void write(JsonWriter out, OffsetDateTime value) throws IOException { + if (value == null) { + out.nullValue(); + } else { + String text = value.format(formatter); + out.value(text); + } + } +} diff --git a/gson/src/main/java/org/onap/policy/common/gson/OffsetTimeTypeAdapter.java b/gson/src/main/java/org/onap/policy/common/gson/OffsetTimeTypeAdapter.java new file mode 100644 index 00000000..49a7d25d --- /dev/null +++ b/gson/src/main/java/org/onap/policy/common/gson/OffsetTimeTypeAdapter.java @@ -0,0 +1,68 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.gson; + +import com.google.gson.JsonParseException; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.time.OffsetTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; + +public class OffsetTimeTypeAdapter extends TypeAdapter { + private DateTimeFormatter formatter; + + public OffsetTimeTypeAdapter() { + this(DateTimeFormatter.ISO_OFFSET_TIME); + } + + public OffsetTimeTypeAdapter(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + @Override + public OffsetTime read(JsonReader in) throws IOException { + try { + if (in.peek() == JsonToken.NULL) { + in.nextNull(); + return null; + } else { + return OffsetTime.parse(in.nextString(), formatter); + } + + } catch (DateTimeParseException e) { + throw new JsonParseException("invalid time", e); + } + } + + @Override + public void write(JsonWriter out, OffsetTime value) throws IOException { + if (value == null) { + out.nullValue(); + } else { + String text = value.format(formatter); + out.value(text); + } + } +} diff --git a/gson/src/main/java/org/onap/policy/common/gson/ZoneOffsetTypeAdapter.java b/gson/src/main/java/org/onap/policy/common/gson/ZoneOffsetTypeAdapter.java new file mode 100644 index 00000000..eb91ac4f --- /dev/null +++ b/gson/src/main/java/org/onap/policy/common/gson/ZoneOffsetTypeAdapter.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.gson; + +import com.google.gson.JsonParseException; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.time.DateTimeException; +import java.time.ZoneOffset; + +public class ZoneOffsetTypeAdapter extends TypeAdapter { + + @Override + public ZoneOffset read(JsonReader in) throws IOException { + try { + if (in.peek() == JsonToken.NULL) { + in.nextNull(); + return null; + } else { + return ZoneOffset.of(in.nextString()); + } + + } catch (DateTimeException e) { + throw new JsonParseException("invalid zone", e); + } + } + + @Override + public void write(JsonWriter out, ZoneOffset value) throws IOException { + if (value == null) { + out.nullValue(); + } else { + out.value(value.toString()); + } + } +} diff --git a/gson/src/test/java/org/onap/policy/common/gson/LocalDateTypeAdapterTest.java b/gson/src/test/java/org/onap/policy/common/gson/LocalDateTypeAdapterTest.java new file mode 100644 index 00000000..17acf5e6 --- /dev/null +++ b/gson/src/test/java/org/onap/policy/common/gson/LocalDateTypeAdapterTest.java @@ -0,0 +1,73 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.gson; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import java.time.LocalDate; +import lombok.ToString; +import org.junit.Test; + +public class LocalDateTypeAdapterTest { + private static Gson gson = + new GsonBuilder().registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter()).create(); + private static final String TEST_DATE = "2020-01-01"; + + @Test + public void test() { + InterestingFields data = new InterestingFields(); + data.date = LocalDate.parse(TEST_DATE); + + String json = gson.toJson(data); + + // instant should be encoded as a number, without quotes + assertThat(json).doesNotContain("year").contains(TEST_DATE); + + InterestingFields data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // try when the date-time string is invalid + String json2 = json.replace("2020", "invalid-date"); + assertThatThrownBy(() -> gson.fromJson(json2, InterestingFields.class)).isInstanceOf(JsonParseException.class) + .hasMessageContaining("invalid date"); + + // null output + data.date = null; + json = gson.toJson(data); + data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // null input + data2 = gson.fromJson("{\"date\":null}", InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + } + + @ToString + private static class InterestingFields { + private LocalDate date; + } + +} diff --git a/gson/src/test/java/org/onap/policy/common/gson/OffsetDateTimeAdapterTest.java b/gson/src/test/java/org/onap/policy/common/gson/OffsetDateTimeAdapterTest.java new file mode 100644 index 00000000..a0bcb1b2 --- /dev/null +++ b/gson/src/test/java/org/onap/policy/common/gson/OffsetDateTimeAdapterTest.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.gson; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import java.time.OffsetDateTime; +import lombok.ToString; +import org.junit.Test; + +public class OffsetDateTimeAdapterTest { + private static Gson gson = + new GsonBuilder().registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeTypeAdapter()).create(); + private static final String TEST_DATE = "2020-01-01T12:00:00.999+05:00"; + + @Test + public void test() { + InterestingFields data = new InterestingFields(); + data.date = OffsetDateTime.parse(TEST_DATE); + + String json = gson.toJson(data); + + // instant should be encoded as a number, without quotes + assertThat(json).doesNotContain("year").contains(TEST_DATE); + + InterestingFields data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // try when the date-time string is invalid + String json2 = json.replace("2020", "invalid-date"); + assertThatThrownBy(() -> gson.fromJson(json2, InterestingFields.class)).isInstanceOf(JsonParseException.class) + .hasMessageContaining("invalid date"); + + // null output + data.date = null; + json = gson.toJson(data); + data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // null input + data2 = gson.fromJson("{\"date\":null}", InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + } + + @ToString + private static class InterestingFields { + private OffsetDateTime date; + } +} diff --git a/gson/src/test/java/org/onap/policy/common/gson/OffsetTimeTypeAdapterTest.java b/gson/src/test/java/org/onap/policy/common/gson/OffsetTimeTypeAdapterTest.java new file mode 100644 index 00000000..8098af98 --- /dev/null +++ b/gson/src/test/java/org/onap/policy/common/gson/OffsetTimeTypeAdapterTest.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.gson; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import java.time.OffsetTime; +import lombok.ToString; +import org.junit.Test; + +public class OffsetTimeTypeAdapterTest { + private static Gson gson = + new GsonBuilder().registerTypeAdapter(OffsetTime.class, new OffsetTimeTypeAdapter()).create(); + private static final String TEST_TIME = "12:00:00.999+05:00"; + + @Test + public void test() { + InterestingFields data = new InterestingFields(); + data.time = OffsetTime.parse(TEST_TIME); + + String json = gson.toJson(data); + + // instant should be encoded as a number, without quotes + assertThat(json).doesNotContain("foo").contains(TEST_TIME); + + InterestingFields data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // try when the date-time string is invalid + String json2 = json.replace("12", "invalid-time"); + assertThatThrownBy(() -> gson.fromJson(json2, InterestingFields.class)).isInstanceOf(JsonParseException.class) + .hasMessageContaining("invalid time"); + + // null output + data.time = null; + json = gson.toJson(data); + data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // null input + data2 = gson.fromJson("{\"time\":null}", InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + } + + @ToString + private static class InterestingFields { + private OffsetTime time; + } +} diff --git a/gson/src/test/java/org/onap/policy/common/gson/ZoneOffsetTypeAdapterTest.java b/gson/src/test/java/org/onap/policy/common/gson/ZoneOffsetTypeAdapterTest.java new file mode 100644 index 00000000..d9a33169 --- /dev/null +++ b/gson/src/test/java/org/onap/policy/common/gson/ZoneOffsetTypeAdapterTest.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.gson; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import java.time.ZoneOffset; +import lombok.ToString; +import org.junit.Test; + +public class ZoneOffsetTypeAdapterTest { + private static Gson gson = + new GsonBuilder().registerTypeAdapter(ZoneOffset.class, new ZoneOffsetTypeAdapter()).create(); + private static final String TEST_ZONE = "+05:00"; + + @Test + public void test() { + InterestingFields data = new InterestingFields(); + data.zone = ZoneOffset.of(TEST_ZONE); + + String json = gson.toJson(data); + + // instant should be encoded as a number, without quotes + assertThat(json).doesNotContain("foo").contains(TEST_ZONE); + + InterestingFields data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // try when the date-time string is invalid + String json2 = json.replace("05", "invalid-zone"); + assertThatThrownBy(() -> gson.fromJson(json2, InterestingFields.class)).isInstanceOf(JsonParseException.class) + .hasMessageContaining("invalid zone"); + + // null output + data.zone = null; + json = gson.toJson(data); + data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // null input + data2 = gson.fromJson("{\"zone\":null}", InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + } + + @ToString + private static class InterestingFields { + private ZoneOffset zone; + } +} -- cgit 1.2.3-korg