Skip to content

Commit

Permalink
Change to Immutable JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
hamnis committed Oct 29, 2015
1 parent 586bc4c commit d957dba
Show file tree
Hide file tree
Showing 29 changed files with 522 additions and 824 deletions.
14 changes: 7 additions & 7 deletions pom.xml
Expand Up @@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>net.hamnaberg.rest</groupId>
<artifactId>json-collection</artifactId>
<version>4.1-SNAPSHOT</version>
<version>5.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>JSON Collection</name>
<url>https://github.com/hamnis/json-collection</url>
Expand Down Expand Up @@ -70,14 +70,14 @@

<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.1.1</version>
<groupId>net.hamnaberg.json</groupId>
<artifactId>immutable-json-jackson</artifactId>
<version>2.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.1.1</version>
<groupId>net.hamnaberg.json</groupId>
<artifactId>immutable-json-codec</artifactId>
<version>2.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.damnhandy</groupId>
Expand Down
79 changes: 35 additions & 44 deletions src/main/java/net/hamnaberg/json/Collection.java
Expand Up @@ -16,38 +16,33 @@

package net.hamnaberg.json;

import net.hamnaberg.json.extension.Extended;
import net.hamnaberg.json.io.JacksonStreamingSerializer;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import net.hamnaberg.json.extension.Extended;

import static java.util.Optional.of;
import static java.util.Optional.ofNullable;

public final class Collection extends Extended<Collection> implements Writable {

Collection(ObjectNode value) {
Collection(Json.JObject value) {
super(value);
}

@Override
protected Collection copy(ObjectNode value) {
protected Collection copy(Json.JObject value) {
return new Collection(value);
}

Expand All @@ -61,27 +56,27 @@ public static Collection create(Optional<URI> href,
List<Query> queries,
Optional<Template> template,
Optional<Error> error) {
ObjectNode obj = JsonNodeFactory.instance.objectNode();
obj.put("version", Version.ONE.getIdentifier());
href.ifPresent(value -> obj.put("href", value.toString()));
ArrayList<Map.Entry<String, Json.JValue>> object = new ArrayList<>();
object.add(Json.entry("version", Json.jString(Version.ONE.getIdentifier())));
href.ifPresent(value -> object.add(Json.entry("href", Json.jString(value.toString()))));
if (!links.isEmpty()) {
obj.set("links", links.stream()
.map(Extended::asJson)
.collect(JsonNodeFactory.instance::arrayNode, ArrayNode::add, ArrayNode::addAll));
object.add(Json.entry("links", Json.jArray(links.stream()
.map(Extended::asJson)
.collect(Collectors.toList()))));
}
if (!items.isEmpty()) {
obj.set("items", items.stream()
.map(Extended::asJson)
.collect(JsonNodeFactory.instance::arrayNode, ArrayNode::add, ArrayNode::addAll));
object.add(Json.entry("items", Json.jArray(items.stream()
.map(Extended::asJson)
.collect(Collectors.toList()))));
}
if (!queries.isEmpty()) {
obj.set("queries", queries.stream()
.map(Extended::asJson)
.collect(JsonNodeFactory.instance::arrayNode, ArrayNode::add, ArrayNode::addAll));
object.add(Json.entry("queries", Json.jArray(queries.stream()
.map(Extended::asJson)
.collect(Collectors.toList()))));
}
template.ifPresent(value -> obj.set("template", value.asJson()));
error.ifPresent(value -> obj.set("error", value.asJson()));
Collection coll = new Collection(obj);
template.ifPresent(value -> object.add(Json.entry("template", value.asJson())));
error.ifPresent(value -> object.add(Json.entry("error", value.asJson())));
Collection coll = new Collection(Json.jObject(object));
coll.validate();
return coll;
}
Expand All @@ -91,35 +86,35 @@ public Version getVersion() {
}

public Optional<URI> getHref() {
return delegate.has("href") ? of(URI.create(delegate.get("href").asText())) : Optional.<URI>empty();
return delegate.getAsString("href").map(URI::create);
}

public List<Link> getLinks() {
return delegate.has("links") ? Link.fromArray(delegate.get("links")) : Collections.<Link>emptyList();
return Link.fromArray(delegate.getAsArrayOrEmpty("links"));
}

public List<Item> getItems() {
return delegate.has("items") ? Item.fromArray(delegate.get("items")) : Collections.<Item>emptyList();
return Item.fromArray(delegate.getAsArrayOrEmpty("items"));
}

public List<Query> getQueries() {
return delegate.has("queries") ? Query.fromArray(delegate.get("queries")) : Collections.<Query>emptyList();
return Query.fromArray(delegate.getAsArrayOrEmpty("queries"));
}

public boolean hasTemplate() {
return delegate.has("template");
return delegate.containsKey("template");
}

public Optional<Template> getTemplate() {
return hasTemplate() ? of(new Template((ObjectNode) delegate.get("template"))) : Optional.<Template>empty();
return delegate.getAsObject("template").map(Template::new);
}

public boolean hasError() {
return delegate.has("error");
return delegate.containsKey("error");
}

public Optional<Error> getError() {
return hasError() ? of(new Error((ObjectNode) delegate.get("error"))) : Optional.<Error>empty();
return delegate.getAsObject("error").map(Error::new);
}

public Optional<Link> linkByName(final String name) {
Expand Down Expand Up @@ -197,20 +192,16 @@ public void writeTo(OutputStream stream) throws IOException {
}

public void writeTo(Writer writer) throws IOException {
ObjectMapper mapper = new ObjectMapper();
ObjectNode obj = mapper.createObjectNode();
obj.set("collection", asJson());
mapper.writeValue(writer, obj);
new JacksonStreamingSerializer().write(
Json.jObject("collection", asJson()),
writer
);
}

@Override
public String toString() {
StringWriter writer = new StringWriter();
try {
writeTo(writer);
} catch (IOException ignore) {
}
return writer.toString();
return new JacksonStreamingSerializer().
writeToString(Json.jObject("collection", asJson()));
}

public void validate() {
Expand Down
17 changes: 5 additions & 12 deletions src/main/java/net/hamnaberg/json/DataContainer.java
@@ -1,19 +1,18 @@
package net.hamnaberg.json;

import net.hamnaberg.json.extension.Extended;
import com.fasterxml.jackson.databind.node.ObjectNode;
import net.hamnaberg.json.util.Iterables;

import java.util.*;
import java.util.function.Predicate;

public abstract class DataContainer<A extends DataContainer> extends Extended<A> {
protected DataContainer(ObjectNode delegate) {
protected DataContainer(Json.JObject delegate) {
super(delegate);
}

public Data getData() {
return new Data(delegate.has("data") ? Property.fromData(delegate.get("data")) : Collections.<Property>emptyList());
return new Data(Property.fromData(delegate.getAsArrayOrEmpty("data")));
}

public Map<String, Property> getDataAsMap() {
Expand All @@ -38,9 +37,7 @@ public A replace(Property property) {
Data data = getData();
Data replaced = data.replace(property);
if (!replaced.isEmpty()) {
ObjectNode copied = copyDelegate();
copied.set("data", Property.toArrayNode(replaced));
return copy(copied);
return copy(delegate.put("data", Property.toArrayNode(replaced)));
}
return (A)this;
}
Expand All @@ -67,9 +64,7 @@ public A addAll(Iterable<Property> toAdd) {
return (A)this;
}

ObjectNode copied = copyDelegate();
copied.set("data", Property.toArrayNode(data));
return copy(copied);
return copy(delegate.put("data", Property.toArrayNode(data)));
}

/**
Expand All @@ -83,8 +78,6 @@ public A set(Iterable<Property> props) {
if (Iterables.isEmpty(props)) {
return (A) this;
}
ObjectNode copied = copyDelegate();
copied.set("data", Property.toArrayNode(props));
return copy(copied);
return copy(delegate.put("data", Property.toArrayNode(props)));
}
}
19 changes: 10 additions & 9 deletions src/main/java/net/hamnaberg/json/Error.java
Expand Up @@ -17,9 +17,10 @@
package net.hamnaberg.json;

import net.hamnaberg.json.extension.Extended;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.net.URI;

Expand All @@ -28,12 +29,12 @@
public final class Error extends Extended<Error> {
public static final Error EMPTY = Error.create(Optional.<String>empty(), Optional.<String>empty(), Optional.<String>empty());

Error(ObjectNode delegate) {
Error(Json.JObject delegate) {
super(delegate);
}

@Override
protected Error copy(ObjectNode value) {
protected Error copy(Json.JObject value) {
return new Error(value);
}

Expand Down Expand Up @@ -62,11 +63,11 @@ public static Error create(String title, String code, String message) {
}

public static Error create(Optional<String> title, Optional<String> code, Optional<String> message) {
final ObjectNode obj = JsonNodeFactory.instance.objectNode();
title.ifPresent(value -> obj.put("title", value));
code.ifPresent(value -> obj.put("code", value));
message.ifPresent(value -> obj.put("message", value));
return new Error(obj);
final Map<String, Json.JValue> obj = new LinkedHashMap<>();
title.ifPresent(value -> obj.put("title", Json.jString(value)));
code.ifPresent(value -> obj.put("code", Json.jString(value)));
message.ifPresent(value -> obj.put("message", Json.jString(value)));
return new Error(Json.jObject(obj));
}


Expand Down
13 changes: 6 additions & 7 deletions src/main/java/net/hamnaberg/json/InternalObjectFactory.java
@@ -1,29 +1,28 @@
package net.hamnaberg.json;

import com.fasterxml.jackson.databind.node.ObjectNode;

public abstract class InternalObjectFactory {
public Collection createCollection(ObjectNode node) {
public Collection createCollection(Json.JObject node) {
return new Collection(node);
}

public Error createError(ObjectNode node) {
public Error createError(Json.JObject node) {
return new Error(node);
}

public Link createLink(ObjectNode node) {
public Link createLink(Json.JObject node) {
return new Link(node);
}

public Property createProperty(ObjectNode node) {
public Property createProperty(Json.JObject node) {
return new Property(node);
}

public Query createQuery(ObjectNode node) {
public Query createQuery(Json.JObject node) {
return new Query(node);
}

public Template createTemplate(ObjectNode node) {
public Template createTemplate(Json.JObject node) {
return new Template(node);
}
}

0 comments on commit d957dba

Please sign in to comment.