Skip to content

Commit

Permalink
[json-node] Add equals/hashcode to JsonNode
Browse files Browse the repository at this point in the history
  • Loading branch information
rbygrave committed Dec 12, 2024
1 parent 0422c0d commit d59b19d
Show file tree
Hide file tree
Showing 22 changed files with 374 additions and 3 deletions.
3 changes: 2 additions & 1 deletion blackbox-test/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
requires static io.avaje.jsonb;
requires static io.avaje.spi;
requires java.validation;
requires io.avaje.json.node;

provides io.avaje.jsonb.spi.JsonbExtension with org.example.customer.customtype.CustomTypeComponent, org.example.jsonb.GeneratedJsonComponent;

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.example.customer.node;

import io.avaje.json.node.JsonNode;
import io.avaje.jsonb.Json;

@Json
public record HelloMixed(String name, JsonNode other) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.example.customer.node;

import io.avaje.json.node.JsonObject;
import io.avaje.jsonb.JsonType;
import io.avaje.jsonb.Jsonb;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

class HelloMixedTest {

Jsonb jsonb = Jsonb.builder().build();
JsonType<HelloMixed> jsonType = jsonb.type(HelloMixed.class);

@Test
void test() {
HelloMixed mixed = new HelloMixed("hi", JsonObject.create().add("a", "b"));

String asJson = jsonType.toJson(mixed);
assertThat(asJson).isEqualTo("{\"name\":\"hi\",\"other\":{\"a\":\"b\"}}");

HelloMixed fromJson = jsonType.fromJson(asJson);

assertThat(fromJson).isEqualTo(mixed);
}
}
54 changes: 54 additions & 0 deletions json-core/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# avaje-json-core

Provides the core API including JsonAdapter, JsonReader, JsonWriter, JsonStream API.

## Dependency

```xml
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-json</artifactId>
<version>3.0</version>
</dependency>
```

## SimpleMapper

If you only have simple use cases you can use avaje-json
without avaje-jsonb.

For use cases that only want to map to the following types:
- String
- Boolean
- Integer
- Long
- Double
- Map<String, Object>
- List<Object>

### Create a SimpleMapper

static final SimpleMapper mapper = SimpleMapper.builder().build()


### Map example

var map = Map.of("key", "some value", "otherKey", 42).

String asJson = mapper.toJson(map);

// read json into a Map
Map<String,Object> asMap = mapper.fromJsonObject(asJson);


### List example

var map0 = Map.of("key", "a", "otherKey", 42);
var map1 = Map.of("key", "b", "otherKey", 99);

var list = List.of(map0, map1).

String asJson = mapper.toJson(list);

// read json into a List
List<Object> asList = mapper.fromJsonArray(asJson);
76 changes: 76 additions & 0 deletions json-node/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# avaje-json-node

Provides JsonNode types and associated JsonAdapters.

## Dependency

```xml
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-json-node</artifactId>
<version>3.0</version>
</dependency>
```

## Examples

```java
var jsonObject = JsonObject.create()
.add("person", JsonObject.create().add("name", "myName").add("active", true))
.add("address", JsonObject.create().add("street", "42 some").add("city", "Bar"));
```

```java
var jsonArray = JsonArray.create()
.add(42)
.add("foo");
```


## Extract

One reason for using JsonNode is to ease the filtering and transformation
of json content.

We can use the `extract()` methods to help with the Stream API filtering
and mapping.

```java
JsonObject object = mapper.fromJsonObject(content);
JsonArray arrayWithNestedPerson = (JsonArray) object.get("people");

List<String> lastNames =
arrayWithNestedPerson.stream()
.filter(node -> "family".equals(node.extract("type")))
.map(node -> node.extract("person.lastName"))
.toList();
```
```java
List<JsonNode> peopleNodes =
arrayWithNestedPerson.stream()
.filter(node -> "family".equals(node.extract("type")))
.map(node -> node.extractNode("person"))
.toList();
```


### JsonNodeMapper

If you don't need avaje-jsonb then we can just use JsonNodeMapper.

```java
// create a JsonNodeMapper
static final JsonNodeMapper mapper = JsonNodeMapper.builder().build();
```

```java
JsonArray jsonArray = JsonArray.create()
.add(42)
.add("foo");

var asJson = mapper.toJson(jsonArray);

// read ARRAY from json
JsonArray arrayFromJson = mapper.fromJsonArray(asJson);
```

14 changes: 14 additions & 0 deletions json-node/src/main/java/io/avaje/json/node/JsonArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

import static java.util.Objects.requireNonNull;
Expand Down Expand Up @@ -41,6 +42,19 @@ private JsonArray(List<JsonNode> children) {
this.children = requireNonNull(children);
}

@Override
public boolean equals(Object object) {
if (this == object) return true;
if (!(object instanceof JsonArray)) return false;
JsonArray jsonArray = (JsonArray) object;
return Objects.equals(children, jsonArray.children);
}

@Override
public int hashCode() {
return Objects.hashCode(children);
}

@Override
public String toString() {
return text();
Expand Down
15 changes: 15 additions & 0 deletions json-node/src/main/java/io/avaje/json/node/JsonBoolean.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.avaje.json.node;

import java.util.Objects;

public final /*value*/ class JsonBoolean implements JsonNode {

private final boolean value;
Expand All @@ -12,6 +14,19 @@ private JsonBoolean(boolean value) {
this.value = value;
}

@Override
public boolean equals(Object object) {
if (this == object) return true;
if (!(object instanceof JsonBoolean)) return false;
JsonBoolean that = (JsonBoolean) object;
return value == that.value;
}

@Override
public int hashCode() {
return Objects.hashCode(value);
}

@Override
public String toString() {
return text();
Expand Down
14 changes: 14 additions & 0 deletions json-node/src/main/java/io/avaje/json/node/JsonDecimal.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.avaje.json.JsonWriter;

import java.math.BigDecimal;
import java.util.Objects;

public final /*value*/ class JsonDecimal implements JsonNumber {

Expand All @@ -16,6 +17,19 @@ private JsonDecimal(BigDecimal value) {
this.value = value;
}

@Override
public boolean equals(Object object) {
if (this == object) return true;
if (!(object instanceof JsonDecimal)) return false;
JsonDecimal that = (JsonDecimal) object;
return Objects.equals(value, that.value);
}

@Override
public int hashCode() {
return Objects.hashCode(value);
}

@Override
public String toString() {
return text();
Expand Down
14 changes: 14 additions & 0 deletions json-node/src/main/java/io/avaje/json/node/JsonDouble.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.avaje.json.JsonWriter;

import java.math.BigDecimal;
import java.util.Objects;

public final /*value*/ class JsonDouble implements JsonNumber {

Expand All @@ -16,6 +17,19 @@ private JsonDouble(double value) {
this.value = value;
}

@Override
public boolean equals(Object object) {
if (this == object) return true;
if (!(object instanceof JsonDouble)) return false;
JsonDouble that = (JsonDouble) object;
return Double.compare(value, that.value) == 0;
}

@Override
public int hashCode() {
return Objects.hashCode(value);
}

@Override
public String toString() {
return text();
Expand Down
14 changes: 14 additions & 0 deletions json-node/src/main/java/io/avaje/json/node/JsonInteger.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.avaje.json.JsonWriter;

import java.math.BigDecimal;
import java.util.Objects;

public final /*value*/ class JsonInteger implements JsonNumber {

Expand All @@ -16,6 +17,19 @@ private JsonInteger(int value) {
this.value = value;
}

@Override
public boolean equals(Object object) {
if (this == object) return true;
if (!(object instanceof JsonInteger)) return false;
JsonInteger that = (JsonInteger) object;
return value == that.value;
}

@Override
public int hashCode() {
return Objects.hashCode(value);
}

@Override
public String toString() {
return text();
Expand Down
14 changes: 14 additions & 0 deletions json-node/src/main/java/io/avaje/json/node/JsonLong.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.avaje.json.JsonWriter;

import java.math.BigDecimal;
import java.util.Objects;

public final /*value*/ class JsonLong implements JsonNumber {

Expand All @@ -16,6 +17,19 @@ private JsonLong(long value) {
this.value = value;
}

@Override
public boolean equals(Object object) {
if (this == object) return true;
if (!(object instanceof JsonLong)) return false;
JsonLong jsonLong = (JsonLong) object;
return value == jsonLong.value;
}

@Override
public int hashCode() {
return Objects.hashCode(value);
}

@Override
public String toString() {
return text();
Expand Down
14 changes: 14 additions & 0 deletions json-node/src/main/java/io/avaje/json/node/JsonObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Pattern;

import static java.util.Objects.requireNonNull;
Expand Down Expand Up @@ -44,6 +45,19 @@ private JsonObject(Map<String, JsonNode> children) {
this.children = requireNonNull(children);
}

@Override
public boolean equals(Object object) {
if (this == object) return true;
if (!(object instanceof JsonObject)) return false;
JsonObject that = (JsonObject) object;
return Objects.equals(children, that.children);
}

@Override
public int hashCode() {
return Objects.hashCode(children);
}

@Override
public String toString() {
return text();
Expand Down
Loading

0 comments on commit d59b19d

Please sign in to comment.