diff --git a/blackbox-test/src/main/java/org/example/customer/creator/PropertyCreator.java b/blackbox-test/src/main/java/org/example/customer/creator/PropertyCreator.java new file mode 100644 index 00000000..0aac10f5 --- /dev/null +++ b/blackbox-test/src/main/java/org/example/customer/creator/PropertyCreator.java @@ -0,0 +1,43 @@ +package org.example.customer.creator; + +import io.avaje.jsonb.Json; + +import java.time.Duration; +import java.time.Instant; +import java.util.UUID; + +@Json +public final class PropertyCreator { + + @Json.Property("uid") + private final String identifier; + + @Json.Property("stp") + private final Instant startup; + + @Json.Creator + public PropertyCreator( + String identifier, + Instant startup) { + this.identifier = identifier; + this.startup = startup; + } + + public PropertyCreator(Instant startup) { + this.identifier = Instant.now().toEpochMilli() + "-" + UUID.randomUUID(); + this.startup = startup; + } + + public String identifier() { + return this.identifier; + } + + public Instant startup() { + return this.startup; + } + + @Json.Property("upt") + public Duration uptime() { + return Duration.ofMillis(1); + } +} diff --git a/blackbox-test/src/test/java/org/example/customer/creator/PropertyCreatorTest.java b/blackbox-test/src/test/java/org/example/customer/creator/PropertyCreatorTest.java new file mode 100644 index 00000000..16e020a7 --- /dev/null +++ b/blackbox-test/src/test/java/org/example/customer/creator/PropertyCreatorTest.java @@ -0,0 +1,27 @@ +package org.example.customer.creator; + +import io.avaje.jsonb.Jsonb; +import org.junit.jupiter.api.Test; + +import java.time.Instant; + +import static org.assertj.core.api.Assertions.assertThat; + +class PropertyCreatorTest { + + final Jsonb jsonb = Jsonb.builder().build(); + + @Test + void asJson() { + var instant = Instant.ofEpochMilli(1); + var pc = new PropertyCreator("strVal", instant); + + String json = jsonb.toJson(pc); + PropertyCreator fromJson = jsonb.type(PropertyCreator.class).fromJson(json); + + assertThat(fromJson.identifier()).isEqualTo("strVal"); + assertThat(fromJson.identifier()).isEqualTo(pc.identifier()); + assertThat(fromJson.startup()).isEqualTo(pc.startup()); + assertThat(fromJson.uptime()).isEqualTo(pc.uptime()); + } +} diff --git a/jsonb-generator/src/main/java/io/avaje/jsonb/generator/Processor.java b/jsonb-generator/src/main/java/io/avaje/jsonb/generator/Processor.java index 5498e201..1f07ee9d 100644 --- a/jsonb-generator/src/main/java/io/avaje/jsonb/generator/Processor.java +++ b/jsonb-generator/src/main/java/io/avaje/jsonb/generator/Processor.java @@ -307,6 +307,7 @@ private void writeAdapter(TypeElement typeElement, BeanReader beanReader) { if (beanReader.hasJsonAnnotation()) { logError("Error JsonAdapter due to nonAccessibleField for %s ", beanReader); } + logNote("Skipped writing JsonAdapter for %s due to non accessible fields", beanReader); return; } try { diff --git a/jsonb-generator/src/main/java/io/avaje/jsonb/generator/TypeReader.java b/jsonb-generator/src/main/java/io/avaje/jsonb/generator/TypeReader.java index 640e3b30..e884346e 100644 --- a/jsonb-generator/src/main/java/io/avaje/jsonb/generator/TypeReader.java +++ b/jsonb-generator/src/main/java/io/avaje/jsonb/generator/TypeReader.java @@ -136,9 +136,10 @@ void read(TypeElement type) { for (var param : constructor.getParams()) { var name = param.name(); var element = param.element(); - var matchingField = localFields.stream() - .filter(f -> f.propertyName().equals(name)) - .findFirst(); + var matchingField = + localFields.stream() + .filter(f -> f.propertyName().equals(name) || f.fieldName().equals(name)) + .findFirst(); matchingField.ifPresentOrElse(f -> f.readParam(element), () -> readField(element, localFields)); } } diff --git a/jsonb-generator/src/test/java/io/avaje/jsonb/generator/models/valid/PropertyCreator.java b/jsonb-generator/src/test/java/io/avaje/jsonb/generator/models/valid/PropertyCreator.java new file mode 100644 index 00000000..faca4109 --- /dev/null +++ b/jsonb-generator/src/test/java/io/avaje/jsonb/generator/models/valid/PropertyCreator.java @@ -0,0 +1,90 @@ +package io.avaje.jsonb.generator.models.valid; + +import java.io.IOException; +import java.io.Serializable; +import java.time.Duration; +import java.time.Instant; +import java.time.temporal.Temporal; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.UUID; +import java.util.function.Consumer; + +import io.avaje.jsonb.Json; + +@Json +public final class PropertyCreator { + + private final transient String[] arguments; + + private final transient List> hooks; + + @Json.Property("uid") + private final String identifier; + + @Json.Property("stp") + private final Instant startup; + + @Json.Property("cfg") + private final Properties configuration; + + @Json.Property("ins") + private final Set instances; + + @Json.Creator + public PropertyCreator( + String identifier, + Instant startup, + Properties configuration, + Set instances) { + this.arguments = null; + this.hooks = null; + + this.identifier = identifier; + this.startup = startup; + this.configuration = configuration; + this.instances = null; + } + + public PropertyCreator(String[] arguments, Instant startup) throws IOException { + this.arguments = arguments != null ? arguments : new String[0]; + this.hooks = new ArrayList<>(); + + this.identifier = Instant.now().toEpochMilli() + "-" + UUID.randomUUID(); + this.startup = startup; + + this.configuration = new Properties(); + this.configuration.putAll(System.getenv()); + this.configuration.putAll(System.getProperties()); + + this.instances = new HashSet<>(); + } + + public String[] arguments() { + return arguments; + } + + public String identifier() { + return this.identifier; + } + + public Instant startup() { + return this.startup; + } + + public Properties configuration() { + return this.configuration; + } + + public Set instances() { + return this.instances; + } + + @Json.Property("upt") + public Duration uptime() { + return Duration.ofMillis(1); + } +} diff --git a/jsonb/src/main/java/io/avaje/jsonb/core/JavaTimeAdapters.java b/jsonb/src/main/java/io/avaje/jsonb/core/JavaTimeAdapters.java index 36d4ee9e..c6a9a0ae 100644 --- a/jsonb/src/main/java/io/avaje/jsonb/core/JavaTimeAdapters.java +++ b/jsonb/src/main/java/io/avaje/jsonb/core/JavaTimeAdapters.java @@ -28,6 +28,7 @@ final class JavaTimeAdapters { if (type == ZoneId.class) return JavaTimeAdapters.ZONE_ID_ADAPTER.nullSafe(); if (type == ZoneOffset.class) return JavaTimeAdapters.ZONE_OFFSET_ADAPTER.nullSafe(); if (type == Date.class) return JavaTimeAdapters.UTIL_DATE.nullSafe(); + if (type == Duration.class) return JavaTimeAdapters.DURATION_ADAPTER.nullSafe(); return null; }; @@ -53,6 +54,23 @@ public String toString() { } }; + private static final JsonAdapter DURATION_ADAPTER = new JsonAdapter<>() { + @Override + public Duration fromJson(JsonReader reader) { + return Duration.parse(reader.readString()); + } + + @Override + public void toJson(JsonWriter writer, Duration value) { + writer.value(value.toString()); + } + + @Override + public String toString() { + return "JsonAdapter(Duration)"; + } + }; + private static final JsonAdapter INSTANT_ADAPTER = new JsonAdapter<>() { @Override public Instant fromJson(JsonReader reader) {