Skip to content

Commit

Permalink
[json-node] Add JsonNodeMapper.properties() method
Browse files Browse the repository at this point in the history
Match the feature of SimpleMapper and Jsonb.
  • Loading branch information
rbygrave committed Dec 16, 2024
1 parent fef89cf commit 3bc985e
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 19 deletions.
20 changes: 10 additions & 10 deletions json-core/src/main/java/io/avaje/json/simple/SimpleMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,16 @@ static Builder builder() {
PropertyNames properties(String... names);

/**
* Return a mapper for Object with more reading/writing options.
* Return a Type specific mapper for the given JsonAdapter.
*
* @param customAdapter The custom adapter to use.
* @param <T> The type of the class to map to/from json.
* @return The Type specific mapper.
*/
<T> Type<T> type(JsonAdapter<T> customAdapter);

/**
* Return a mapper for any json content.
*/
Type<Object> object();

Expand All @@ -66,15 +75,6 @@ static Builder builder() {
*/
Type<List<Object>> list();

/**
* Return a Type specific mapper for the given JsonAdapter.
*
* @param customAdapter The custom adapter to use.
* @param <T> The type of the class to map to/from json.
* @return The Type specific mapper.
*/
<T> Type<T> type(JsonAdapter<T> customAdapter);

/**
* Write the object to JSON string.
* <p>
Expand Down
23 changes: 16 additions & 7 deletions json-node/src/main/java/io/avaje/json/node/JsonNodeMapper.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.avaje.json.node;

import io.avaje.json.JsonAdapter;
import io.avaje.json.PropertyNames;
import io.avaje.json.node.adapter.NodeAdapterBuilder;
import io.avaje.json.simple.SimpleMapper;
import io.avaje.json.stream.JsonStream;
Expand All @@ -19,8 +20,8 @@
* static final JsonNodeMapper mapper = JsonNodeMapper.builder().build();
*
* JsonArray jsonArray = JsonArray.create()
* .add(JsonInteger.of(42))
* .add(JsonString.of("foo"));
* .add(42)
* .add("foo");
*
* var asJson = mapper.toJson(jsonArray);
*
Expand All @@ -42,13 +43,21 @@ static Builder builder() {
}

/**
* Create a NodeMapper for the specific type given the JsonAdapter.
* Return the property names as PropertyNames.
* <p>
* Provides the option of optimising the writing of json for property names
* by having them already escaped and encoded rather than as plain strings.
*/
PropertyNames properties(String... names);

/**
* Return a Type specific mapper for the given JsonAdapter.
*
* @param customAdapter The type specific JsonAdapter to use.
* @param <T> The specific custom type being mapped.
* @return The type specific NodeMapper.
* @param customAdapter The custom adapter to use.
* @param <T> The type of the class to map to/from json.
* @return The Type specific mapper.
*/
<T> SimpleMapper.Type<T> mapper(JsonAdapter<T> customAdapter);
<T> SimpleMapper.Type<T> type(JsonAdapter<T> customAdapter);

/**
* Return a NodeMapper for ANY json content.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.avaje.json.JsonAdapter;
import io.avaje.json.JsonReader;
import io.avaje.json.PropertyNames;
import io.avaje.json.node.*;
import io.avaje.json.simple.SimpleMapper;
import io.avaje.json.stream.JsonStream;
Expand Down Expand Up @@ -31,7 +32,12 @@ final class DJsonNodeMapper implements JsonNodeMapper {
}

@Override
public <T> SimpleMapper.Type<T> mapper(JsonAdapter<T> customAdapter) {
public PropertyNames properties(String... names) {
return jsonStream.properties(names);
}

@Override
public <T> SimpleMapper.Type<T> type(JsonAdapter<T> customAdapter) {
return new DMapper<>(customAdapter, jsonStream);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.avaje.json.JsonAdapter;
import io.avaje.json.JsonReader;
import io.avaje.json.JsonWriter;
import io.avaje.json.PropertyNames;
import io.avaje.json.simple.SimpleMapper;
import org.junit.jupiter.api.Test;

Expand All @@ -16,7 +17,21 @@ class CustomAdapterTest {

static final JsonNodeMapper mapper = JsonNodeMapper.builder().build();
static final MyAdapter myAdapter = new MyAdapter(mapper);
static final SimpleMapper.Type<MyCustomType> typeMapper = mapper.mapper(myAdapter);
static final SimpleMapper.Type<MyCustomType> typeMapper = mapper.type(myAdapter);

@Test
void propertyNames() {

var adapter = new MyAdapter2(mapper);
SimpleMapper.Type<MyCustomType> type = mapper.type(adapter);

var source = as("a", 1);
String asJson = type.toJson(source);
assertThat(asJson).isEqualTo("{\"foo\":\"a\",\"bar\":1}");

MyCustomType myCustomType = type.fromJson(asJson);
assertThat(myCustomType).isEqualTo(source);
}

@Test
void mapUsingCustomAdapter() {
Expand Down Expand Up @@ -110,4 +125,48 @@ public MyCustomType fromJson(JsonReader reader) {
return myCustomType;
}
}

static class MyAdapter2 implements JsonAdapter<MyCustomType> {

final SimpleMapper.Type<JsonObject> objectMapper;
final PropertyNames names;

public MyAdapter2(JsonNodeMapper mapper) {
this.objectMapper = mapper.objectMapper();
this.names = mapper.properties("foo", "bar");
}

@Override
public void toJson(JsonWriter writer, MyCustomType value) {
writer.beginObject(names);
writer.name(0);
writer.value(value.foo);
writer.name(1);
writer.value(value.bar);
writer.endObject();
}

@Override
public MyCustomType fromJson(JsonReader reader) {
MyCustomType myCustomType = new MyCustomType();
reader.beginObject(names);

String name;
while (reader.hasNextField()) {
name = reader.nextField();
switch (name) {
case "foo":
myCustomType.foo = reader.readString();
break;
case "bar":
myCustomType.bar = reader.readInt();
break;
default:
reader.unmappedField(name);
reader.skipValue();
}
}
return myCustomType;
}
}
}

0 comments on commit 3bc985e

Please sign in to comment.