Skip to content
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.example.customer.subtype;

import org.example.customer.subtype.Dessendre.Alicia;
import org.example.customer.subtype.Dessendre.Curator;
import org.example.customer.subtype.Dessendre.Paintress;

import io.avaje.jsonb.Json.SubType;

@io.avaje.jsonb.Json
@SubType(type = Alicia.class, name = "Maelle")
@SubType(type = Paintress.class, name = "Aline")
@SubType(type = Curator.class, name = "Renoir")
public sealed interface Dessendre {
public record Alicia() implements Dessendre {}

public record Paintress() implements Dessendre {}

public record Curator() implements Dessendre {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.example.customer.subtype;

import io.avaje.jsonb.Json;

@Json
@Json.SubType(type = EmptySupertype.SubtypeA.class, name = "a")
@Json.SubType(type = EmptySupertype.SubtypeB.class, name = "b")
public sealed interface EmptySupertype {
record SubtypeA() implements EmptySupertype {}
record SubtypeB() implements EmptySupertype {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package org.example.customer.subtype;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import org.junit.jupiter.api.Test;

import io.avaje.json.JsonAdapter;
import io.avaje.jsonb.JsonType;
import io.avaje.jsonb.Jsonb;

class EmptySupertypeTest {
Jsonb jsonb = Jsonb.builder().build();
JsonAdapter<EmptySupertype> adapter = jsonb.adapter(EmptySupertype.class);
JsonType<EmptySupertype> type = jsonb.type(EmptySupertype.class);

@Test
void nullObject() {
var object = (EmptySupertype) null;
var expected = "";
var actual = type.toJson(object);
assertEquals(expected, actual);
}

@Test
void objectA() {
var object = new EmptySupertype.SubtypeA();
var expected = "{\"@type\":\"a\"}";
var actual = type.toJson(object);
assertEquals(expected, actual);
}

@Test
void jsonA() {
var json = "{\"@type\":\"a\"}";
var expected = new EmptySupertype.SubtypeA();
var actual = type.fromJson(json);
assertEquals(expected, actual);
}

@Test
void objectB() {
var object = new EmptySupertype.SubtypeB();
var expected = "{\"@type\":\"b\"}";
var actual = type.toJson(object);
assertEquals(expected, actual);
}

@Test
void jsonB() {
var json = "{\"@type\":\"b\"}";
var expected = new EmptySupertype.SubtypeB();
var actual = type.fromJson(json);
assertEquals(expected, actual);
}

@Test
void invalidJsonC() {
var json = "{\"@type\":\"c\"}";
assertThrows(IllegalStateException.class, () -> type.fromJson(json));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;

import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
Expand Down Expand Up @@ -291,47 +292,32 @@ public void writeConstructor(Append writer) {
}
}
writer.append(" this.names = jsonb.properties(");
var properties = new LinkedHashSet<String>();
if (hasSubTypes) {
writer.append("\"").append(typeProperty).append("\", ");
properties.add('"' + typeProperty + '"');
}
writer.append(propertyNames());
properties.addAll(propertyNames());
writer.append(String.join(", ", properties));
writer.append(");").eol();
}

private String propertyNames() {
private List<String> propertyNames() {
return readOnlyInterface ? propertyNamesReadOnly() : propertyNamesFields();
}

private String propertyNamesFields() {
final StringBuilder builder = new StringBuilder();
//set to prevent writing same key twice
final var seen = new HashSet<String>();
for (int i = 0, size = allFields.size(); i < size; i++) {
final FieldReader fieldReader = allFields.get(i);
if (!seen.add(fieldReader.propertyName())) {
continue;
}
if (i > 0) {
builder.append(", ");
}
if (usesTypeProperty && fieldReader.propertyName().equals(typePropertyKey())) {
builder.append(" ");
continue;
}
builder.append("\"").append(fieldReader.propertyName()).append("\"");
}
return builder.toString().replace(" , ", "");
private List<String> propertyNamesFields() {
return allFields.stream()
.map(FieldReader::propertyName)
.map(property -> '"' + property + '"')
.filter(property -> !usesTypeProperty || !property.equals(typePropertyKey()))
.collect(toList());
}

private String propertyNamesReadOnly() {
final StringBuilder builder = new StringBuilder();
for (int i = 0; i < methodProperties.size(); i++) {
if (i > 0) {
builder.append(", ");
}
builder.append("\"").append(methodProperties.get(i).propertyName()).append("\"");
}
return builder.toString().replace(" , ", "");
private List<String> propertyNamesReadOnly() {
return methodProperties.stream()
.map(MethodProperty::propertyName)
.map(property -> '"' + property + '"')
.collect(toList());
}

@Override
Expand Down