mirror of
https://github.com/ChronosX88/JGUN.git
synced 2024-11-23 23:12:18 +00:00
Make node values type-safe
This commit is contained in:
parent
b83e3ee14e
commit
45e013098f
@ -1,88 +0,0 @@
|
||||
package io.github.chronosx88.JGUN;
|
||||
|
||||
import io.github.chronosx88.JGUN.models.MemoryGraph;
|
||||
import io.github.chronosx88.JGUN.models.Node;
|
||||
import io.github.chronosx88.JGUN.models.NodeLink;
|
||||
import io.github.chronosx88.JGUN.models.NodeMetadata;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
|
||||
public class NodeArrayBuilder {
|
||||
private final MemoryGraph graph;
|
||||
private final Node rootNode;
|
||||
private final List<Object> innerArray;
|
||||
protected static final String ARRAY_FIELD = "__ARRAY__";
|
||||
|
||||
public NodeArrayBuilder() {
|
||||
this.graph = MemoryGraph.builder().build();
|
||||
this.innerArray = new ArrayList<>();
|
||||
this.rootNode = Node.builder()
|
||||
.metadata(NodeMetadata.builder()
|
||||
.nodeID(null)
|
||||
.states(new HashMap<>(Map.of(ARRAY_FIELD, System.currentTimeMillis())))
|
||||
.build())
|
||||
.values(Map.of(ARRAY_FIELD, innerArray))
|
||||
.build();
|
||||
graph.nodes.put(GraphNodeBuilder.ROOT_NODE, this.rootNode);
|
||||
}
|
||||
|
||||
private NodeArrayBuilder addScalar(Object value) {
|
||||
this.innerArray.add(value);
|
||||
this.rootNode.getMetadata().getStates().put(ARRAY_FIELD, System.currentTimeMillis());
|
||||
return this;
|
||||
}
|
||||
|
||||
public NodeArrayBuilder add(String value) {
|
||||
return addScalar(value);
|
||||
}
|
||||
|
||||
public NodeArrayBuilder add(BigInteger value) {
|
||||
return addScalar(value);
|
||||
}
|
||||
|
||||
public NodeArrayBuilder add(BigDecimal value) {
|
||||
return addScalar(value);
|
||||
}
|
||||
|
||||
public NodeArrayBuilder add(int value) {
|
||||
return addScalar(value);
|
||||
}
|
||||
|
||||
public NodeArrayBuilder add(long value) {
|
||||
return addScalar(value);
|
||||
}
|
||||
|
||||
public NodeArrayBuilder add(double value) {
|
||||
return addScalar(value);
|
||||
}
|
||||
|
||||
public NodeArrayBuilder add(boolean value) {
|
||||
return addScalar(value);
|
||||
|
||||
}
|
||||
|
||||
public NodeArrayBuilder addNull(String name) {
|
||||
return addScalar(null);
|
||||
}
|
||||
|
||||
public NodeArrayBuilder add(GraphNodeBuilder builder) {
|
||||
String newNodeID = UUID.randomUUID().toString();
|
||||
//noinspection unchecked
|
||||
List<Object> innerArray = (List<Object>) rootNode.values.get(ARRAY_FIELD);
|
||||
innerArray.add(NodeLink.builder()
|
||||
.link(newNodeID)
|
||||
.build());
|
||||
MemoryGraph innerGraph = builder.build();
|
||||
innerGraph.nodes.get(GraphNodeBuilder.ROOT_NODE).getMetadata().setNodeID(newNodeID);
|
||||
innerGraph.nodes.put(newNodeID, innerGraph.nodes.get(GraphNodeBuilder.ROOT_NODE));
|
||||
innerGraph.nodes.remove(GraphNodeBuilder.ROOT_NODE);
|
||||
this.graph.nodes.putAll(innerGraph.nodes);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MemoryGraph build() {
|
||||
return this.graph;
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package io.github.chronosx88.JGUN;
|
||||
package io.github.chronosx88.JGUN.api;
|
||||
|
||||
import io.github.chronosx88.JGUN.models.Node;
|
||||
import io.github.chronosx88.JGUN.models.graph.Node;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface NodeChangeListener {
|
@ -0,0 +1,87 @@
|
||||
package io.github.chronosx88.JGUN.api.graph;
|
||||
|
||||
import io.github.chronosx88.JGUN.models.graph.MemoryGraph;
|
||||
import io.github.chronosx88.JGUN.models.graph.Node;
|
||||
import io.github.chronosx88.JGUN.models.graph.NodeValue;
|
||||
import io.github.chronosx88.JGUN.models.graph.values.*;
|
||||
import io.github.chronosx88.JGUN.models.graph.NodeMetadata;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
|
||||
public class ArrayBuilder {
|
||||
private final MemoryGraph graph;
|
||||
private final Node rootNode;
|
||||
private final List<NodeValue> innerArray;
|
||||
protected static final String ARRAY_FIELD = "__ARRAY__";
|
||||
|
||||
public ArrayBuilder() {
|
||||
this.graph = new MemoryGraph();
|
||||
this.innerArray = new ArrayList<>();
|
||||
this.rootNode = Node.builder()
|
||||
.metadata(NodeMetadata.builder()
|
||||
.nodeID(null)
|
||||
.states(new HashMap<>(Map.of(ARRAY_FIELD, System.currentTimeMillis())))
|
||||
.build())
|
||||
.values(Map.of(ARRAY_FIELD, new ArrayValue(this.innerArray)))
|
||||
.build();
|
||||
graph.nodes.put(NodeBuilder.ROOT_NODE, this.rootNode);
|
||||
}
|
||||
|
||||
private ArrayBuilder addScalar(NodeValue value) {
|
||||
this.innerArray.add(value);
|
||||
this.rootNode.getMetadata().getStates().put(ARRAY_FIELD, System.currentTimeMillis());
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArrayBuilder add(String value) {
|
||||
return addScalar(new StringValue(value));
|
||||
}
|
||||
|
||||
public ArrayBuilder add(BigInteger value) {
|
||||
return addScalar(new IntValue(value));
|
||||
}
|
||||
|
||||
public ArrayBuilder add(BigDecimal value) {
|
||||
return addScalar(new DecimalValue(value));
|
||||
}
|
||||
|
||||
public ArrayBuilder add(int value) {
|
||||
return addScalar(new IntValue(value));
|
||||
}
|
||||
|
||||
public ArrayBuilder add(long value) {
|
||||
return addScalar(new IntValue(value));
|
||||
}
|
||||
|
||||
public ArrayBuilder add(double value) {
|
||||
return addScalar(new DecimalValue(value));
|
||||
}
|
||||
|
||||
public ArrayBuilder add(boolean value) {
|
||||
return addScalar(new BooleanValue(value));
|
||||
}
|
||||
|
||||
public ArrayBuilder addNull(String name) {
|
||||
return addScalar(null);
|
||||
}
|
||||
|
||||
public ArrayBuilder add(NodeBuilder builder) {
|
||||
String newNodeID = UUID.randomUUID().toString();
|
||||
List<NodeValue> innerArray = ((ArrayValue) rootNode.values.get(ARRAY_FIELD)).getValue();
|
||||
innerArray.add(NodeLinkValue.builder()
|
||||
.link(newNodeID)
|
||||
.build());
|
||||
MemoryGraph innerGraph = builder.build();
|
||||
innerGraph.nodes.get(NodeBuilder.ROOT_NODE).getMetadata().setNodeID(newNodeID);
|
||||
innerGraph.nodes.put(newNodeID, innerGraph.nodes.get(NodeBuilder.ROOT_NODE));
|
||||
innerGraph.nodes.remove(NodeBuilder.ROOT_NODE);
|
||||
this.graph.nodes.putAll(innerGraph.nodes);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MemoryGraph build() {
|
||||
return this.graph;
|
||||
}
|
||||
}
|
@ -1,22 +1,21 @@
|
||||
package io.github.chronosx88.JGUN;
|
||||
package io.github.chronosx88.JGUN.api.graph;
|
||||
|
||||
import io.github.chronosx88.JGUN.models.MemoryGraph;
|
||||
import io.github.chronosx88.JGUN.models.Node;
|
||||
import io.github.chronosx88.JGUN.models.NodeLink;
|
||||
import io.github.chronosx88.JGUN.models.NodeMetadata;
|
||||
import io.github.chronosx88.JGUN.models.graph.*;
|
||||
import io.github.chronosx88.JGUN.models.graph.values.*;
|
||||
import io.github.chronosx88.JGUN.models.graph.NodeValue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class GraphNodeBuilder {
|
||||
public class NodeBuilder {
|
||||
private final MemoryGraph graph;
|
||||
private final Node rootNode;
|
||||
protected static final String ROOT_NODE = "__ROOT__";
|
||||
|
||||
public GraphNodeBuilder() {
|
||||
this.graph = MemoryGraph.builder().build();
|
||||
public NodeBuilder() {
|
||||
this.graph = new MemoryGraph();
|
||||
this.rootNode = Node.builder()
|
||||
.metadata(NodeMetadata.builder()
|
||||
.nodeID(null)
|
||||
@ -25,48 +24,47 @@ public class GraphNodeBuilder {
|
||||
graph.nodes.put(ROOT_NODE, this.rootNode);
|
||||
}
|
||||
|
||||
private GraphNodeBuilder addScalar(String name, Object value) {
|
||||
private NodeBuilder addScalar(String name, NodeValue value) {
|
||||
rootNode.values.put(name, value);
|
||||
rootNode.getMetadata().getStates().put(name, System.currentTimeMillis());
|
||||
return this;
|
||||
}
|
||||
|
||||
public GraphNodeBuilder add(String name, String value) {
|
||||
return addScalar(name, value);
|
||||
public NodeBuilder add(String name, String value) {
|
||||
return addScalar(name, new StringValue(value));
|
||||
}
|
||||
|
||||
public GraphNodeBuilder add(String name, BigInteger value) {
|
||||
return addScalar(name, value);
|
||||
public NodeBuilder add(String name, BigInteger value) {
|
||||
return addScalar(name, new IntValue(value));
|
||||
}
|
||||
|
||||
public GraphNodeBuilder add(String name, BigDecimal value) {
|
||||
return addScalar(name, value);
|
||||
public NodeBuilder add(String name, BigDecimal value) {
|
||||
return addScalar(name, new DecimalValue(value));
|
||||
}
|
||||
|
||||
public GraphNodeBuilder add(String name, int value) {
|
||||
return addScalar(name, value);
|
||||
public NodeBuilder add(String name, int value) {
|
||||
return addScalar(name, new IntValue(value));
|
||||
}
|
||||
|
||||
public GraphNodeBuilder add(String name, long value) {
|
||||
return addScalar(name, value);
|
||||
public NodeBuilder add(String name, long value) {
|
||||
return addScalar(name, new IntValue(value));
|
||||
}
|
||||
|
||||
public GraphNodeBuilder add(String name, double value) {
|
||||
return addScalar(name, value);
|
||||
public NodeBuilder add(String name, double value) {
|
||||
return addScalar(name, new DecimalValue(value));
|
||||
}
|
||||
|
||||
public GraphNodeBuilder add(String name, boolean value) {
|
||||
return addScalar(name, value);
|
||||
|
||||
public NodeBuilder add(String name, boolean value) {
|
||||
return addScalar(name, new BooleanValue(value));
|
||||
}
|
||||
|
||||
public GraphNodeBuilder addNull(String name) {
|
||||
public NodeBuilder addNull(String name) {
|
||||
return addScalar(name, null);
|
||||
}
|
||||
|
||||
public GraphNodeBuilder add(String name, GraphNodeBuilder builder) {
|
||||
public NodeBuilder add(String name, NodeBuilder builder) {
|
||||
String newNodeID = UUID.randomUUID().toString();
|
||||
rootNode.values.put(name, NodeLink.builder()
|
||||
rootNode.values.put(name, NodeLinkValue.builder()
|
||||
.link(newNodeID)
|
||||
.build());
|
||||
MemoryGraph innerGraph = builder.build();
|
||||
@ -77,17 +75,16 @@ public class GraphNodeBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public GraphNodeBuilder add(String name, NodeArrayBuilder builder) {
|
||||
public NodeBuilder add(String name, ArrayBuilder builder) {
|
||||
MemoryGraph innerGraph = builder.build();
|
||||
//noinspection unchecked
|
||||
var innerArray = (List<Object>) innerGraph.nodes.get(ROOT_NODE).values.get(NodeArrayBuilder.ARRAY_FIELD);
|
||||
var innerArray = (NodeValue) innerGraph.nodes.get(ROOT_NODE).values.get(ArrayBuilder.ARRAY_FIELD);
|
||||
rootNode.values.put(name, innerArray);
|
||||
rootNode.getMetadata().getStates().put(name, innerGraph
|
||||
.nodes
|
||||
.get(ROOT_NODE)
|
||||
.getMetadata()
|
||||
.getStates()
|
||||
.get(NodeArrayBuilder.ARRAY_FIELD));
|
||||
.get(ArrayBuilder.ARRAY_FIELD));
|
||||
innerGraph.nodes.remove(ROOT_NODE);
|
||||
graph.nodes.putAll(innerGraph.nodes);
|
||||
return this;
|
@ -1,14 +0,0 @@
|
||||
package io.github.chronosx88.JGUN.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@Jacksonized
|
||||
public class NodeLink {
|
||||
@JsonProperty("#")
|
||||
String link;
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
package io.github.chronosx88.JGUN.models.acks;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.github.chronosx88.JGUN.models.MemoryGraph;
|
||||
import lombok.Builder;
|
||||
import io.github.chronosx88.JGUN.models.graph.MemoryGraph;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
@ -1,6 +1,4 @@
|
||||
package io.github.chronosx88.JGUN.models;
|
||||
|
||||
import lombok.Getter;
|
||||
package io.github.chronosx88.JGUN.models.graph;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Delayed;
|
||||
@ -9,7 +7,7 @@ import java.util.concurrent.TimeUnit;
|
||||
public class DeferredNode extends Node implements Delayed {
|
||||
private long deferredUntil = 0;
|
||||
|
||||
DeferredNode(NodeMetadata metadata, Map<String, Object> values) {
|
||||
DeferredNode(NodeMetadata metadata, Map<String, NodeValue> values) {
|
||||
super(metadata, values);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package io.github.chronosx88.JGUN.models;
|
||||
package io.github.chronosx88.JGUN.models.graph;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
@ -11,12 +11,9 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@Jacksonized
|
||||
public class MemoryGraph {
|
||||
@JsonIgnore
|
||||
@Builder.Default
|
||||
public final Map<String, Node> nodes = new LinkedHashMap<>();
|
||||
public Map<String, Node> nodes = new LinkedHashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, Node> nodes() {
|
@ -1,34 +1,38 @@
|
||||
package io.github.chronosx88.JGUN.models;
|
||||
package io.github.chronosx88.JGUN.models.graph;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@Jacksonized
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Node {
|
||||
@JsonProperty("_")
|
||||
private NodeMetadata metadata;
|
||||
@Builder.Default
|
||||
private final NodeMetadata metadata = new NodeMetadata(new HashMap<>(), null);
|
||||
|
||||
@JsonIgnore
|
||||
@Builder.Default
|
||||
public Map<String, Object> values = new LinkedHashMap<>(); // Data
|
||||
public final Map<String, NodeValue> values = new LinkedHashMap<>(); // Data
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, Object> getValues() {
|
||||
public Map<String, NodeValue> getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void allSetter(String key, String value) {
|
||||
public void allSetter(String key, NodeValue value) {
|
||||
values.put(key, value);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package io.github.chronosx88.JGUN.models;
|
||||
package io.github.chronosx88.JGUN.models.graph;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Builder;
|
@ -0,0 +1,19 @@
|
||||
package io.github.chronosx88.JGUN.models.graph;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
|
||||
//@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
|
||||
@JsonDeserialize(using = NodeValueDeserializer.class)
|
||||
public interface NodeValue {
|
||||
enum ValueType {
|
||||
ARRAY,
|
||||
STRING,
|
||||
INTEGER,
|
||||
DECIMAL,
|
||||
BOOLEAN,
|
||||
NULL,
|
||||
LINK
|
||||
}
|
||||
|
||||
ValueType getValueType();
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package io.github.chronosx88.JGUN.models.graph;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import io.github.chronosx88.JGUN.models.graph.values.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class NodeValueDeserializer extends JsonDeserializer<NodeValue> {
|
||||
@Override
|
||||
public NodeValue deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
|
||||
JsonNode node = p.readValueAsTree();
|
||||
return parseValue(node);
|
||||
}
|
||||
|
||||
private NodeValue parseValue(JsonNode node) throws JsonProcessingException {
|
||||
if (node.isBoolean()) {
|
||||
return new BooleanValue(node.booleanValue());
|
||||
} else if (node.isBigDecimal()) {
|
||||
return new DecimalValue(node.decimalValue());
|
||||
} else if (node.isFloat()) {
|
||||
return new DecimalValue(node.floatValue());
|
||||
} else if (node.isDouble()) {
|
||||
return new DecimalValue(node.doubleValue());
|
||||
} else if (node.isTextual()) {
|
||||
return new StringValue(node.textValue());
|
||||
} else if (node.isInt()) {
|
||||
return new IntValue(node.intValue());
|
||||
} else if (node.isBigInteger()) {
|
||||
return new IntValue(node.bigIntegerValue());
|
||||
} else if (node.isLong()) {
|
||||
return new IntValue(node.longValue());
|
||||
} else if (node.isObject()) {
|
||||
if (node.has("#")) {
|
||||
return NodeLinkValue.builder()
|
||||
.link(node.get("#").textValue())
|
||||
.build();
|
||||
} else {
|
||||
throw new IllegalArgumentException("node can have only links, not actual objects");
|
||||
}
|
||||
} else if (node.isArray()) {
|
||||
ArrayValue value = new ArrayValue();
|
||||
for (JsonNode arrayItem : node) {
|
||||
value.getValue().add(parseValue(arrayItem));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
throw new IllegalArgumentException("unsupported node value");
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package io.github.chronosx88.JGUN.models.graph.values;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import io.github.chronosx88.JGUN.models.graph.NodeValue;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
public class ArrayValue implements NodeValue {
|
||||
@JsonValue
|
||||
private List<NodeValue> value = new ArrayList<>();
|
||||
|
||||
@JsonCreator
|
||||
public ArrayValue(NodeValue[] value) {
|
||||
this.value = new ArrayList<>(List.of(value));
|
||||
}
|
||||
|
||||
public ArrayValue(List<NodeValue> value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueType getValueType() {
|
||||
return ValueType.ARRAY;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package io.github.chronosx88.JGUN.models.graph.values;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import io.github.chronosx88.JGUN.models.graph.NodeValue;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class BooleanValue implements NodeValue {
|
||||
@JsonValue
|
||||
private boolean value;
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
|
||||
public BooleanValue(boolean value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeValue.ValueType getValueType() {
|
||||
return NodeValue.ValueType.BOOLEAN;
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package io.github.chronosx88.JGUN.models.graph.values;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import io.github.chronosx88.JGUN.models.graph.NodeValue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class DecimalValue implements NodeValue {
|
||||
@JsonValue
|
||||
private BigDecimal value;
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
|
||||
public DecimalValue(double num) {
|
||||
this.value = BigDecimal.valueOf(num);
|
||||
}
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
|
||||
public DecimalValue(float num) {
|
||||
this.value = BigDecimal.valueOf(num);
|
||||
}
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
|
||||
public DecimalValue(BigDecimal value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueType getValueType() {
|
||||
return ValueType.DECIMAL;
|
||||
}
|
||||
|
||||
public double getDouble() {
|
||||
return value.floatValue();
|
||||
}
|
||||
|
||||
public float getFloat() {
|
||||
return value.floatValue();
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package io.github.chronosx88.JGUN.models.graph.values;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import io.github.chronosx88.JGUN.models.graph.NodeValue;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class IntValue implements NodeValue {
|
||||
@JsonValue
|
||||
public BigInteger value;
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
|
||||
public IntValue(int value) {
|
||||
this.value = BigInteger.valueOf(value);
|
||||
}
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
|
||||
public IntValue(long value) {
|
||||
this.value = BigInteger.valueOf(value);
|
||||
}
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
|
||||
public IntValue(BigInteger value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getInt() {
|
||||
return value.intValue();
|
||||
}
|
||||
|
||||
public BigInteger getBig() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public long getLong() {
|
||||
return value.longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueType getValueType() {
|
||||
return ValueType.INTEGER;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package io.github.chronosx88.JGUN.models.graph.values;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.github.chronosx88.JGUN.models.graph.NodeValue;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@Jacksonized
|
||||
public class NodeLinkValue implements NodeValue {
|
||||
@JsonProperty("#")
|
||||
private String link;
|
||||
|
||||
@Override
|
||||
@JsonIgnore
|
||||
public ValueType getValueType() {
|
||||
return ValueType.LINK;
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package io.github.chronosx88.JGUN.models.graph.values;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import io.github.chronosx88.JGUN.models.graph.NodeValue;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class StringValue implements NodeValue {
|
||||
@JsonValue
|
||||
private String value;
|
||||
|
||||
@JsonCreator
|
||||
public StringValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueType getValueType() {
|
||||
return ValueType.STRING;
|
||||
}
|
||||
|
||||
}
|
@ -3,8 +3,8 @@ package io.github.chronosx88.JGUN.storage;
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.Expiry;
|
||||
import io.github.chronosx88.JGUN.models.DeferredNode;
|
||||
import io.github.chronosx88.JGUN.models.Node;
|
||||
import io.github.chronosx88.JGUN.models.graph.DeferredNode;
|
||||
import io.github.chronosx88.JGUN.models.graph.Node;
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
|
||||
import java.util.Collection;
|
||||
|
@ -1,11 +1,8 @@
|
||||
package io.github.chronosx88.JGUN.storage;
|
||||
|
||||
import io.github.chronosx88.JGUN.HAM;
|
||||
import io.github.chronosx88.JGUN.NodeChangeListener;
|
||||
import io.github.chronosx88.JGUN.models.DeferredNode;
|
||||
import io.github.chronosx88.JGUN.models.MemoryGraph;
|
||||
import io.github.chronosx88.JGUN.models.Node;
|
||||
import io.github.chronosx88.JGUN.models.NodeMetadata;
|
||||
import io.github.chronosx88.JGUN.api.NodeChangeListener;
|
||||
import io.github.chronosx88.JGUN.models.graph.*;
|
||||
import io.github.chronosx88.JGUN.models.graph.NodeValue;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -36,7 +33,7 @@ public abstract class Storage {
|
||||
*/
|
||||
public void mergeUpdate(MemoryGraph update) {
|
||||
long machine = System.currentTimeMillis();
|
||||
MemoryGraph diff = MemoryGraph.builder().build();
|
||||
MemoryGraph diff = new MemoryGraph();
|
||||
for (Map.Entry<String, Node> entry : update.getNodes().entrySet()) {
|
||||
Node node = entry.getValue();
|
||||
Node diffNode = this.mergeNode(node, machine);
|
||||
@ -57,7 +54,7 @@ public abstract class Storage {
|
||||
changeListeners.get(diffEntry.getKey()).forEach((e) -> e.onChange(diffEntry.getValue()));
|
||||
}
|
||||
if (mapChangeListeners.containsKey(diffEntry.getKey())) {
|
||||
for (Map.Entry<String, Object> nodeEntry : changedNode.getValues().entrySet()) {
|
||||
for (Map.Entry<String, NodeValue> nodeEntry : changedNode.getValues().entrySet()) {
|
||||
mapChangeListeners.get(nodeEntry.getKey()).forEach((e) -> e.onChange(nodeEntry.getKey(), nodeEntry.getValue()));
|
||||
}
|
||||
}
|
||||
@ -75,7 +72,7 @@ public abstract class Storage {
|
||||
public Node mergeNode(Node incomingNode, long machineState) {
|
||||
Node changedNode = null;
|
||||
for (String key : incomingNode.getValues().keySet()) {
|
||||
Object value = incomingNode.getValues().get(key);
|
||||
NodeValue value = incomingNode.getValues().get(key);
|
||||
long state = incomingNode.getMetadata().getStates().get(key);
|
||||
long previousState = -1;
|
||||
Object currentValue = null;
|
||||
|
@ -3,61 +3,72 @@ package io.github.chronosx88.JGUN;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
|
||||
import io.github.chronosx88.JGUN.api.graph.NodeBuilder;
|
||||
import io.github.chronosx88.JGUN.api.graph.ArrayBuilder;
|
||||
import io.github.chronosx88.JGUN.models.graph.MemoryGraph;
|
||||
import io.github.chronosx88.JGUN.models.graph.values.IntValue;
|
||||
import io.github.chronosx88.JGUN.models.graph.values.NodeLinkValue;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class GraphNodeBuilderTest {
|
||||
|
||||
@Test
|
||||
void Test_sampleGraph1() {
|
||||
void Test_sampleGraph1() throws JsonProcessingException {
|
||||
var objectMapper = new ObjectMapper();
|
||||
objectMapper.registerModule(new Jdk8Module());
|
||||
|
||||
var graph = new GraphNodeBuilder()
|
||||
var graph = new NodeBuilder()
|
||||
.add("firstName", "John")
|
||||
.add("lastName", "Smith")
|
||||
.add("age", 25)
|
||||
.add("address", new GraphNodeBuilder()
|
||||
.add("address", new NodeBuilder()
|
||||
.add("streetAddress", "21 2nd Street")
|
||||
.add("city", "New York")
|
||||
.add("state", "NY")
|
||||
.add("postalCode", "10021"))
|
||||
.add("phoneNumber", new NodeArrayBuilder()
|
||||
.add(new GraphNodeBuilder()
|
||||
.add("phoneNumber", new ArrayBuilder()
|
||||
.add(new NodeBuilder()
|
||||
.add("type", "home")
|
||||
.add("number", "212 555-1234"))
|
||||
.add(new GraphNodeBuilder()
|
||||
.add(new NodeBuilder()
|
||||
.add("type", "fax")
|
||||
.add("number", "646 555-4567")))
|
||||
.addNull("heh")
|
||||
.build();
|
||||
|
||||
String graphJSON = null;
|
||||
try {
|
||||
graphJSON = objectMapper.writeValueAsString(graph);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
System.out.println(graphJSON);
|
||||
String graphJSON1 = objectMapper.writeValueAsString(graph);
|
||||
System.out.println(graphJSON1);
|
||||
|
||||
graph = objectMapper.readValue(graphJSON1, MemoryGraph.class);
|
||||
String graphJSON2 = objectMapper.writeValueAsString(graph);
|
||||
System.out.println(graphJSON2);
|
||||
|
||||
assertEquals(graphJSON1, graphJSON2);
|
||||
assertEquals(((IntValue) graph.nodes.get("__ROOT__").getValues().get("age")).getInt(), 25);
|
||||
assertTrue(graph.nodes.get("__ROOT__").getValues().get("address") instanceof NodeLinkValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
void Test_sampleGraph2() {
|
||||
void Test_sampleGraph2() throws JsonProcessingException {
|
||||
var objectMapper = new ObjectMapper();
|
||||
objectMapper.registerModule(new Jdk8Module());
|
||||
|
||||
var graph = new GraphNodeBuilder()
|
||||
.add("a", new NodeArrayBuilder()
|
||||
.add(new GraphNodeBuilder()
|
||||
.add("b", new GraphNodeBuilder()
|
||||
var graph = new NodeBuilder()
|
||||
.add("a", new ArrayBuilder()
|
||||
.add(new NodeBuilder()
|
||||
.add("b", new NodeBuilder()
|
||||
.add("c", true)))
|
||||
.add(0))
|
||||
.build();
|
||||
|
||||
String graphJSON = null;
|
||||
try {
|
||||
String graphJSON = objectMapper.writeValueAsString(graph);
|
||||
System.out.println(graphJSON);
|
||||
|
||||
graph = objectMapper.readValue(graphJSON, MemoryGraph.class);
|
||||
graphJSON = objectMapper.writeValueAsString(graph);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
System.out.println(graphJSON);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user