Skip to content

Commit c39b7e6

Browse files
committed
Add allNames() and use that for JsonViews
1 parent edbc1ef commit c39b7e6

File tree

13 files changed

+269
-26
lines changed

13 files changed

+269
-26
lines changed

blackbox-test/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@
2626
<version>0.11-SNAPSHOT</version>
2727
</dependency>
2828

29+
<!-- <dependency>-->
30+
<!-- <groupId>io.avaje</groupId>-->
31+
<!-- <artifactId>avaje-jsonb-jackson</artifactId>-->
32+
<!-- <version>0.11-SNAPSHOT</version>-->
33+
<!-- </dependency>-->
34+
2935
<dependency>
3036
<groupId>io.avaje</groupId>
3137
<artifactId>avaje-jsonb-generator</artifactId>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package org.example.customer.views;
2+
3+
public class VAddress {
4+
5+
String street;
6+
String suburb;
7+
String city;
8+
9+
public String street() {
10+
return street;
11+
}
12+
13+
public VAddress street(String street) {
14+
this.street = street;
15+
return this;
16+
}
17+
18+
public String suburb() {
19+
return suburb;
20+
}
21+
22+
public VAddress suburb(String suburb) {
23+
this.suburb = suburb;
24+
return this;
25+
}
26+
27+
public String city() {
28+
return city;
29+
}
30+
31+
public VAddress city(String city) {
32+
this.city = city;
33+
return this;
34+
}
35+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.example.customer.views;
2+
3+
public class VContact {
4+
5+
private final Long id;
6+
private final String firstName;
7+
private final String lastName;
8+
9+
public VContact(Long id, String firstName, String lastName) {
10+
this.id = id;
11+
this.firstName = firstName;
12+
this.lastName = lastName;
13+
}
14+
15+
public Long id() {
16+
return id;
17+
}
18+
19+
public String firstName() {
20+
return firstName;
21+
}
22+
23+
public String lastName() {
24+
return lastName;
25+
}
26+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package org.example.customer.views;
2+
3+
import io.avaje.jsonb.Json;
4+
5+
import java.time.Instant;
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
9+
@Json
10+
public class VCustomer {
11+
12+
Integer id;
13+
String name;
14+
Instant whenCreated;
15+
VAddress billingAddress;
16+
List<VContact> contacts = new ArrayList<>();
17+
18+
public Integer id() {
19+
return id;
20+
}
21+
22+
public VCustomer id(Integer id) {
23+
this.id = id;
24+
return this;
25+
}
26+
27+
public String name() {
28+
return name;
29+
}
30+
31+
public VCustomer name(String name) {
32+
this.name = name;
33+
return this;
34+
}
35+
36+
public Instant whenCreated() {
37+
return whenCreated;
38+
}
39+
40+
public VCustomer whenCreated(Instant whenCreated) {
41+
this.whenCreated = whenCreated;
42+
return this;
43+
}
44+
45+
public VAddress billingAddress() {
46+
return billingAddress;
47+
}
48+
49+
public VCustomer billingAddress(VAddress billingAddress) {
50+
this.billingAddress = billingAddress;
51+
return this;
52+
}
53+
54+
public List<VContact> contacts() {
55+
return contacts;
56+
}
57+
58+
public VCustomer contacts(List<VContact> contacts) {
59+
this.contacts = contacts;
60+
return this;
61+
}
62+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package org.example.customer.views;
2+
3+
import io.avaje.jsonb.JsonView;
4+
import io.avaje.jsonb.Jsonb;
5+
import org.junit.jupiter.api.Test;
6+
7+
import java.time.Instant;
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
11+
import static org.assertj.core.api.Assertions.assertThat;
12+
13+
class ViewTest {
14+
15+
Jsonb jsonb = Jsonb.newBuilder().build();
16+
17+
@Test
18+
void jsonView_sameInstance() {
19+
JsonView<VCustomer> v0 = jsonb.type(VCustomer.class).view("(id, name, billingAddress(street), contacts(id, lastName))");
20+
JsonView<VCustomer> v1 = jsonb.type(VCustomer.class).view("(id, name, billingAddress(street), contacts(id, lastName))");
21+
22+
assertThat(v0).isSameAs(v1);
23+
}
24+
25+
@Test
26+
void jsonView_differentInstance_byDsl() {
27+
JsonView<VCustomer> v0 = jsonb.type(VCustomer.class).view("(id, name)");
28+
JsonView<VCustomer> v1 = jsonb.type(VCustomer.class).view("(id, name )");
29+
assertThat(v0).isNotSameAs(v1);
30+
}
31+
32+
@Test
33+
void jsonView_differentInstance_byType() {
34+
JsonView<?> v0 = jsonb.type(VCustomer.class).view("(id, name)");
35+
JsonView<?> v1 = jsonb.type(VContact.class).view("(id, name)");
36+
assertThat(v0).isNotSameAs(v1);
37+
}
38+
39+
@Test
40+
void jsonView() {
41+
42+
JsonView<VCustomer> customerJsonView = jsonb.type(VCustomer.class).view("(id, name, billingAddress(street), contacts(id, lastName))");
43+
44+
VAddress billingAddress = new VAddress().street("my street").suburb("my suburb");
45+
VCustomer customer = new VCustomer().id(42).name("rob").whenCreated(Instant.now()).billingAddress(billingAddress);
46+
customer.contacts().add(new VContact(7L, "fo", "nar"));
47+
customer.contacts().add(new VContact(8L, "ba", "zar"));
48+
49+
String asJson = customerJsonView.toJson(customer);
50+
assertThat(asJson).isEqualTo("{\"id\":42,\"name\":\"rob\",\"billingAddress\":{\"street\":\"my street\"},\"contacts\":[{\"id\":7,\"lastName\":\"nar\"},{\"id\":8,\"lastName\":\"zar\"}]}");
51+
}
52+
53+
@Test
54+
void jsonView_list() {
55+
56+
JsonView<List<VCustomer>> customerJsonView = jsonb.type(VCustomer.class).list().view("(id, name, contacts(*))");
57+
58+
VAddress billingAddress = new VAddress().street("my street").suburb("my suburb");
59+
VCustomer customer0 = new VCustomer().id(42).name("rob").whenCreated(Instant.now()).billingAddress(billingAddress);
60+
VCustomer customer1 = new VCustomer().id(43).name("bob").whenCreated(Instant.now()).billingAddress(billingAddress);
61+
customer0.contacts().add(new VContact(7L, "fo", "nar"));
62+
customer0.contacts().add(new VContact(8L, "ba", "zar"));
63+
64+
List<VCustomer> customers = new ArrayList<>();
65+
customers.add(customer0);
66+
customers.add(customer1);
67+
68+
String asJson = customerJsonView.toJson(customers);
69+
assertThat(asJson).isEqualTo("[{\"id\":42,\"name\":\"rob\",\"contacts\":[{\"id\":7,\"firstName\":\"fo\",\"lastName\":\"nar\"},{\"id\":8,\"firstName\":\"ba\",\"lastName\":\"zar\"}]},{\"id\":43,\"name\":\"bob\"}]");
70+
}
71+
}

jsonb-jackson/src/main/java/io/avaje/jsonb/jackson/JacksonWriter.java

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ final class JacksonWriter implements JsonWriter {
1818
private boolean serializeEmpty;
1919
private boolean serializeNulls;
2020
private String deferredName;
21-
private ArrayStack<JacksonNames> nameStack;
21+
private final ArrayStack<JacksonNames> nameStack = new ArrayStack<>();
2222
private JacksonNames currentNames;
23-
private boolean pushedNames;
23+
private boolean allNames;
2424
private int namePos = -1;
2525

2626
JacksonWriter(JsonGenerator generator, boolean serializeNulls, boolean serializeEmpty) {
@@ -114,9 +114,8 @@ public void beginObject() {
114114
public void endObject() {
115115
try {
116116
generator.writeEndObject();
117-
if (pushedNames) {
118-
pushedNames = false;
119-
currentNames = nameStack != null ? nameStack.pop() : null;
117+
if (!allNames) {
118+
currentNames = nameStack.pop();
120119
}
121120
} catch (IOException e) {
122121
throw new JsonIoException(e);
@@ -129,21 +128,17 @@ public void name(String name) {
129128
}
130129

131130
@Override
132-
public void names(PropertyNames nextNames) {
133-
if (currentNames != nextNames) {
134-
if (currentNames != null) {
135-
pushCurrentNames();
136-
}
137-
currentNames = (JacksonNames) nextNames;
138-
}
131+
public void allNames(PropertyNames names) {
132+
allNames = true;
133+
currentNames = (JacksonNames) names;
139134
}
140135

141-
private void pushCurrentNames() {
142-
if (nameStack == null) {
143-
nameStack = new ArrayStack<>();
136+
@Override
137+
public void names(PropertyNames names) {
138+
if (currentNames != null) {
139+
nameStack.push(currentNames);
144140
}
145-
pushedNames = true;
146-
nameStack.push(currentNames);
141+
currentNames = (JacksonNames) names;
147142
}
148143

149144
@Override

jsonb-jakarta/src/main/java/io/avaje/jsonb/jakarta/JakartaJsonWriter.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ public String path() {
5555
return null;
5656
}
5757

58+
@Override
59+
public void allNames(PropertyNames names) {
60+
this.names = (DPropertyNames) names;
61+
}
62+
5863
@Override
5964
public void names(PropertyNames names) {
6065
this.names = (DPropertyNames) names;

jsonb/src/main/java/io/avaje/jsonb/JsonWriter.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,27 @@ public interface JsonWriter extends Closeable, Flushable {
5757
*/
5858
String path();
5959

60+
/**
61+
* Set the property names that will be used for all json generation.
62+
* <p>
63+
* These names should be used for all json generation for this generator and set once
64+
* rather than set per object via {@link #names(PropertyNames)}.
65+
* <p>
66+
* This is used by view json generation where all the names are known at the point
67+
* when the view is created (a sort of flattened nested tree).
68+
*/
69+
void allNames(PropertyNames names);
70+
6071
/**
6172
* Set the current property names.
73+
* <p>
74+
* This is expected to be called per object after each call to {@link #beginObject()}.
6275
*/
6376
void names(PropertyNames names);
6477

6578
/**
66-
* Set the next property name to write by position.
79+
* Set the next property name to write by position. This uses the already encoded
80+
* name values of PropertyNames.
6781
*/
6882
void name(int position);
6983

jsonb/src/main/java/io/avaje/jsonb/core/ViewBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ public byte[] toJsonBytes(T value) {
221221
@Override
222222
public void toJson(T value, JsonWriter writer) {
223223
if (properties != null) {
224-
writer.names(properties);
224+
writer.allNames(properties);
225225
}
226226
try {
227227
element.write(writer, value);

jsonb/src/main/java/io/avaje/jsonb/spi/DelegateJsonWriter.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ public final void name(String name) {
7676
delegate.name(name);
7777
}
7878

79+
@Override
80+
public void allNames(PropertyNames names) {
81+
delegate.allNames(names);
82+
}
83+
7984
@Override
8085
public final void names(PropertyNames names) {
8186
delegate.names(names);

0 commit comments

Comments
 (0)