Skip to content

Commit

Permalink
[json-node] Rename JsonNodeAdapter to JsonNodeMapper (#306)
Browse files Browse the repository at this point in the history
* [json-node] Rename JsonNodeAdapter to JsonNodeMapper

Although this provides all the JsonAdapters for the JsonNode types, for developers using it directly they will view it more like a "mapper" with convenience methods for toJson() and fromJson()

* [json-node] Add NodeMapper API for reading/writing options using all options like InputStream, OutputStream etc
  • Loading branch information
rbygrave authored Dec 12, 2024
1 parent 197301b commit cc526c1
Show file tree
Hide file tree
Showing 13 changed files with 549 additions and 175 deletions.
3 changes: 1 addition & 2 deletions json-core/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
module io.avaje.json {

exports io.avaje.json;
exports io.avaje.json.core to io.avaje.jsonb;
exports io.avaje.json.stream;
exports io.avaje.json.stream.core;
exports io.avaje.json.view;
exports io.avaje.json.core to io.avaje.jsonb;

requires static io.helidon.webserver;
}
118 changes: 0 additions & 118 deletions json-node/src/main/java/io/avaje/json/node/JsonNodeAdapter.java

This file was deleted.

178 changes: 178 additions & 0 deletions json-node/src/main/java/io/avaje/json/node/JsonNodeMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
package io.avaje.json.node;

import io.avaje.json.JsonAdapter;
import io.avaje.json.node.adapter.NodeAdapterBuilder;
import io.avaje.json.stream.JsonStream;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Type;

/**
* Provide JsonAdapters for the JsonNode types.
*
* <pre>{@code
*
* static final JsonNodeMapper mapper = JsonNodeMapper.builder().build();
*
* JsonArray jsonArray = JsonArray.create()
* .add(JsonInteger.of(42))
* .add(JsonString.of("foo"));
*
* var asJson = mapper.toJson(jsonArray);
*
* JsonNode jsonNodeFromJson = mapper.fromJson(asJson);
* assertThat(jsonNodeFromJson).isInstanceOf(JsonArray.class);
*
* JsonArray arrayFromJson = mapper.fromJson(JsonArray.class, asJson);
* assertThat(arrayFromJson.elements()).hasSize(2);
*
* }</pre>
*/
public interface JsonNodeMapper {

/**
* Create a Builder for the JsonNodeAdapter.
*/
static Builder builder() {
return new NodeAdapterBuilder();
}

/**
* Return a NodeMapper for ANY json content.
* <p>
* The NodeMapper provides support for all reading and writing options
* such as InputStream, OutputStream, Reader, Writer etc.
*/
NodeMapper<JsonNode> nodeMapper();

/**
* Return a NodeMapper for json OBJECT content.
* <p>
* The NodeMapper provides support for all reading and writing options
* such as InputStream, OutputStream, Reader, Writer etc.
*/
NodeMapper<JsonObject> objectMapper();

/**
* Return a NodeMapper for json ARRAY content.
* <p>
* The NodeMapper provides support for all reading and writing options
* such as InputStream, OutputStream, Reader, Writer etc.
*/
NodeMapper<JsonArray> arrayMapper();

/**
* Write the node to JSON string.
* <p>
* For options to write json content to OutputStream, Writer etc
* use {@link #nodeMapper()}.
*
* <pre>{@code
* static final JsonNodeMapper mapper = JsonNodeMapper.builder().build();
*
* JsonArray jsonArray = JsonArray.create()
* .add(JsonInteger.of(42))
* .add(JsonString.of("foo"));
*
* var asJson = mapper.toJson(jsonArray);
* }</pre>
*
* @see NodeMapper#toJson(JsonNode, OutputStream)
* @see NodeMapper#toJson(JsonNode, Writer)
*/
String toJson(JsonNode node);

/**
* Read any json content returning a JsonNode.
* <p>
* For options to read json content from InputStream, Reader etc
* use the fromJson methods on {@link NodeMapper}.
*
* <pre>{@code
* static final JsonNodeMapper mapper = JsonNodeMapper.builder().build();
*
* JsonNode nodeFromJson = mapper.fromJson(jsonContent);
* }</pre>
*
* @see NodeMapper#fromJson(Reader)
* @see NodeMapper#fromJson(InputStream)
*/
JsonNode fromJson(String json);

/**
* Read a JsonObject from json string content.
* <p>
* Use this when we know that the json content is a JsonObject.
*
* @param json The json content.
* @return The JsonObject parsed from the content.
*/
JsonObject fromJsonObject(String json);

/**
* Read a JsonArray from json string content.
* <p>
* Use this when we know that the json content is a JsonArray.
*
* @param json The json content.
* @return The JsonArray parsed from the content.
*/
JsonArray fromJsonArray(String json);

/**
* Helper method to read JSON with an expected JsonNode type.
*
* <pre>{@code
* static final JsonNodeMapper mapper = JsonNodeMapper.builder().build();
*
* JsonArray arrayFromJson = mapper.fromJson(JsonArray.class, jsonContent);
* }</pre>
*/
<T extends JsonNode> T fromJson(Class<T> type, String json);

/**
* Return the JsonAdapter for the given JsonNode type.
*
* @param type The JsonNode type
* @return The adapter for the given type
*/
<T extends JsonNode> JsonAdapter<T> adapter(Class<T> type);

/**
* Create a JsonAdapter for the given generic type or null if the
* type is not actually a JsonNode type.
*/
JsonAdapter<?> adapter(Type type);

/**
* Build the JsonNodeMapper.
*/
interface Builder {

/**
* Set the default JsonStream to use when using {@link JsonNodeMapper#toJson(JsonNode)}
* {@link JsonNodeMapper#fromJson(String)}.
* <p>
* When not set this defaults to {@code JsonStream.builder().build()}.
*
* @see JsonStream#builder()
*/
Builder jsonStream(JsonStream jsonStream);

/**
* Set the adapter to use when reading {@link JsonNode.Type#NUMBER}.
* <p>
* The default will read as a double and test for the value being an
* integral returning a long if is.
*/
Builder numberAdapter(JsonAdapter<JsonNumber> numberAdapter);

/**
* Build and return the JsonNodeMapper.
*/
JsonNodeMapper build();
}
}
78 changes: 78 additions & 0 deletions json-node/src/main/java/io/avaje/json/node/NodeMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package io.avaje.json.node;

import io.avaje.json.JsonReader;
import io.avaje.json.JsonWriter;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;

/**
* Mappers for JsonNode, JsonArray and JsonObject.
* <p>
* This supports more options for reading and writing json content
* such as InputStream, OutputStream, Reader, Writer etc.
*
* @see JsonNodeMapper#arrayMapper()
* @see JsonNodeMapper#objectMapper()
* @see JsonNodeMapper#nodeMapper()
*/
public interface NodeMapper<T extends JsonNode> {

/**
* Read the return the value from the json content.
*/
T fromJson(String content);

/**
* Read the return the value from the reader.
*/
T fromJson(JsonReader reader);

/**
* Read the return the value from the json content.
*/
T fromJson(byte[] content);

/**
* Read the return the value from the reader.
*/
T fromJson(Reader reader);

/**
* Read the return the value from the inputStream.
*/
T fromJson(InputStream inputStream);

/**
* Return as json string.
*/
String toJson(T value);

/**
* Return as json string in pretty format.
*/
String toJsonPretty(T value);

/**
* Return the value as json content in bytes form.
*/
byte[] toJsonBytes(T value);

/**
* Write to the given writer.
*/
void toJson(T value, JsonWriter writer);

/**
* Write to the given writer.
*/
void toJson(T value, Writer writer);

/**
* Write to the given outputStream.
*/
void toJson(T value, OutputStream outputStream);

}
Loading

0 comments on commit cc526c1

Please sign in to comment.