Skip to content

Commit

Permalink
Remove Guava. Build and tests now run on Java 6-11.
Browse files Browse the repository at this point in the history
  • Loading branch information
soberich committed Nov 2, 2019
1 parent ce6f3a8 commit a381e35
Showing 18 changed files with 235 additions and 145 deletions.
4 changes: 1 addition & 3 deletions project.gradle
Original file line number Diff line number Diff line change
@@ -30,8 +30,7 @@ targetCompatibility = JavaVersion.VERSION_1_7; // defaults to sourceCompatibilit
*/
dependencies {
implementation(group: "com.fasterxml.jackson.core", name: "jackson-databind", version: "2.9.9");
implementation(group: "com.google.guava", name: "guava", version: "28.1-android");
implementation(group: "com.github.java-json-tools", name: "msg-simple", version: "1.2-SNAPSHOT");
implementation(group: "com.github.fge", name: "msg-simple", version: "1.1");
implementation(group: "com.google.code.findbugs", name: "jsr305", version: "2.0.1");
testImplementation(group: "org.testng", name: "testng", version: "6.8.7") {
exclude(group: "junit", module: "junit");
@@ -51,7 +50,6 @@ javadoc {
links("https://docs.oracle.com/javase/7/docs/api/");
links("https://www.javadoc.io/doc/com.google.code.findbugs/jsr305/3.0.1/");
links("https://fasterxml.github.io/jackson-databind/javadoc/2.2.0/");
links("https://www.javadoc.io/doc/com.google.guava/guava/28.1-android/");
links("https://java-json-tools.github.io/msg-simple/");
}
}
7 changes: 4 additions & 3 deletions src/main/java/com/github/fge/jackson/JacksonUtils.java
Original file line number Diff line number Diff line change
@@ -29,10 +29,11 @@
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.google.common.collect.Maps;

import java.io.IOException;
import java.io.StringWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@@ -94,11 +95,11 @@ public static JsonNodeFactory nodeFactory()
*/
public static Map<String, JsonNode> asMap(final JsonNode node)
{
final Map<String, JsonNode> ret = Maps.newHashMap();
if (!node.isObject())
return ret;
return Collections.emptyMap();

final Iterator<Map.Entry<String, JsonNode>> iterator = node.fields();
final Map<String, JsonNode> ret = new HashMap<String, JsonNode>();

Map.Entry<String, JsonNode> entry;

65 changes: 29 additions & 36 deletions src/main/java/com/github/fge/jackson/JsonLoader.java
Original file line number Diff line number Diff line change
@@ -20,11 +20,8 @@
package com.github.fge.jackson;

import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.Preconditions;
import com.google.common.io.Closer;

import javax.annotation.Nonnull;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@@ -74,50 +71,44 @@ private JsonLoader()
public static JsonNode fromResource(@Nonnull final String resource)
throws IOException
{
Preconditions.checkNotNull(resource);
Preconditions.checkArgument(resource.startsWith("/"),
"resource path does not start with a '/'");
if (resource == null) {
throw new NullPointerException();
}
if (!resource.startsWith("/")) {
throw new IllegalArgumentException("resource path does not start with a '/'");
}
URL url;
url = JsonLoader.class.getResource(resource);
if (url == null) {
final ClassLoader classLoader = firstNonNull(
Thread.currentThread().getContextClassLoader(),
JsonLoader.class.getClassLoader()
);
final ClassLoader classLoader;
if (Thread.currentThread().getContextClassLoader() != null) {
classLoader = Thread.currentThread().getContextClassLoader();
} else if (JsonLoader.class.getClassLoader() != null) {
classLoader = JsonLoader.class.getClassLoader();
} else {
throw new NullPointerException();
}
final String s = INITIAL_SLASH.matcher(resource).replaceFirst("");
url = classLoader.getResource(s);
}
if (url == null)
throw new IOException("resource " + resource + " not found");

final Closer closer = Closer.create();
final JsonNode ret;
final InputStream in;
InputStream in = null;

try {
in = closer.register(url.openStream());
in = url.openStream();
ret = READER.fromInputStream(in);
} finally {
closer.close();
if (in != null) {
in.close();
}
}

return ret;
}

/**
* Returns the first non-null parameter.
*
* Implementation note: Avoids the Guava method of the same name, to mitigate 'Dependency Hell'.
* This can be replaced by {@code MoreObjects.firstNonNull} when moving to Guava >= 18.0
* (Tip: Guava 20 seems like a good choice if Java 6 support is still necessary.)
*
* @throws NullPointerException if both are null.
*/
private static ClassLoader firstNonNull(ClassLoader first, ClassLoader second)
{
return first != null ? first : Preconditions.checkNotNull(second);
}

/**
* Read a {@link JsonNode} from an URL.
*
@@ -141,15 +132,16 @@ public static JsonNode fromURL(final URL url)
public static JsonNode fromPath(final String path)
throws IOException
{
final Closer closer = Closer.create();
final JsonNode ret;
final FileInputStream in;
FileInputStream in = null;

try {
in = closer.register(new FileInputStream(path));
in = new FileInputStream(path);
ret = READER.fromInputStream(in);
} finally {
closer.close();
if (in != null) {
in.close();
}
}

return ret;
@@ -166,15 +158,16 @@ public static JsonNode fromPath(final String path)
public static JsonNode fromFile(final File file)
throws IOException
{
final Closer closer = Closer.create();
final JsonNode ret;
final FileInputStream in;
FileInputStream in = null;

try {
in = closer.register(new FileInputStream(file));
in = new FileInputStream(file);
ret = READER.fromInputStream(in);
} finally {
closer.close();
if (in != null) {
in.close();
}
}

return ret;
33 changes: 20 additions & 13 deletions src/main/java/com/github/fge/jackson/JsonNodeReader.java
Original file line number Diff line number Diff line change
@@ -30,7 +30,6 @@
import com.github.fge.Builder;
import com.github.fge.msgsimple.bundle.MessageBundle;
import com.github.fge.msgsimple.bundle.PropertiesBundle;
import com.google.common.io.Closer;

import javax.annotation.Nonnull;
import javax.annotation.concurrent.ThreadSafe;
@@ -93,16 +92,20 @@ public JsonNodeReader()
public JsonNode fromInputStream(final InputStream in)
throws IOException
{
final Closer closer = Closer.create();
final JsonParser parser;
final MappingIterator<JsonNode> iterator;
JsonParser parser = null;
MappingIterator<JsonNode> iterator = null;

try {
parser = closer.register(reader.getFactory().createParser(in));
parser = reader.getFactory().createParser(in);
iterator = reader.readValues(parser);
return readNode(closer.register(iterator));
return readNode(iterator);
} finally {
closer.close();
if (parser != null) {
parser.close();
}
if (iterator != null) {
iterator.close();
}
}
}

@@ -117,16 +120,20 @@ public JsonNode fromInputStream(final InputStream in)
public JsonNode fromReader(final Reader r)
throws IOException
{
final Closer closer = Closer.create();
final JsonParser parser;
final MappingIterator<JsonNode> iterator;
JsonParser parser = null;
MappingIterator<JsonNode> iterator = null;

try {
parser = closer.register(reader.getFactory().createParser(r));
parser = reader.getFactory().createParser(r);
iterator = reader.readValues(parser);
return readNode(closer.register(iterator));
return readNode(iterator);
} finally {
closer.close();
if (parser != null) {
parser.close();
}
if (iterator != null) {
iterator.close();
}
}
}

94 changes: 83 additions & 11 deletions src/main/java/com/github/fge/jackson/JsonNumEquals.java
Original file line number Diff line number Diff line change
@@ -20,15 +20,15 @@
package com.github.fge.jackson;

import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.Equivalence;
import com.google.common.collect.Sets;

import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
* An {@link Equivalence} strategy for JSON Schema equality
* An {@code com.google.common.base.Equivalence} like strategy for JSON Schema equality
*
* <p>{@link JsonNode} does a pretty good job of obeying the {@link
* Object#equals(Object) equals()}/{@link Object#hashCode() hashCode()}
@@ -41,21 +41,50 @@
* kind of equality.</p>
*/
public final class JsonNumEquals
extends Equivalence<JsonNode>
{
private static final Equivalence<JsonNode> INSTANCE
private static final JsonNumEquals INSTANCE
= new JsonNumEquals();

private JsonNumEquals()
{
}

public static Equivalence<JsonNode> getInstance()
public static JsonNumEquals getInstance()
{
return INSTANCE;
}

@Override
/**
* Returns {@code true} if the given objects are considered equivalent.
*
* <p>The {@code equivalent} method implements an equivalence relation on object references:
*
* <ul>
* <li>It is <i>reflexive</i>: for any reference {@code x}, including null, {@code
* equivalent(x, x)} returns {@code true}.
* <li>It is <i>symmetric</i>: for any references {@code x} and {@code y}, {@code
* equivalent(x, y) == equivalent(y, x)}.
* <li>It is <i>transitive</i>: for any references {@code x}, {@code y}, and {@code z}, if
* {@code equivalent(x, y)} returns {@code true} and {@code equivalent(y, z)} returns {@code
* true}, then {@code equivalent(x, z)} returns {@code true}.
* <li>It is <i>consistent</i>: for any references {@code x} and {@code y}, multiple invocations
* of {@code equivalent(x, y)} consistently return {@code true} or consistently return {@code
* false} (provided that neither {@code x} nor {@code y} is modified).
* </ul>
* @param a x
* @param b y
* @return whether nodes are equal according to IETF RFCs
*/
public final boolean equivalent(@Nullable JsonNode a, @Nullable JsonNode b) {
if (a == b) {
return true;
}
if (a == null || b == null) {
return false;
}
return doEquivalent(a, b);
}

protected boolean doEquivalent(final JsonNode a, final JsonNode b)
{
/*
@@ -93,7 +122,31 @@ protected boolean doEquivalent(final JsonNode a, final JsonNode b)
return typeA == NodeType.ARRAY ? arrayEquals(a, b) : objectEquals(a, b);
}

@Override
/**
* Returns a hash code for {@code t}.
*
* <p>The {@code hash} has the following properties:
* <ul>
* <li>It is <i>consistent</i>: for any reference {@code x}, multiple invocations of
* {@code hash(x}} consistently return the same value provided {@code x} remains unchanged
* according to the definition of the equivalence. The hash need not remain consistent from
* one execution of an application to another execution of the same application.
* <li>It is <i>distributable across equivalence</i>: for any references {@code x} and {@code y},
* if {@code equivalent(x, y)}, then {@code hash(x) == hash(y)}. It is <i>not</i> necessary
* that the hash be distributable across <i>inequivalence</i>. If {@code equivalence(x, y)}
* is false, {@code hash(x) == hash(y)} may still be true.
* <li>{@code hash(null)} is {@code 0}.
* </ul>
* @param t node to hash
* @return hash
*/
public final int hash(@Nullable JsonNode t) {
if (t == null) {
return 0;
}
return doHash(t);
}

protected int doHash(final JsonNode t)
{
/*
@@ -183,13 +236,32 @@ private boolean objectEquals(final JsonNode a, final JsonNode b)
/*
* Grab the key set from the first node
*/
final Set<String> keys = Sets.newHashSet(a.fieldNames());

final Set<String> keys = new HashSet<String>();
Iterator<String> iterator1 = a.fieldNames();
while (iterator1.hasNext()) {
final String next = iterator1.next();
if (next != null) {
keys.add(next);
} else {
throw new NullPointerException();
}
}
// final Set<String> keys = Sets.newHashSet(a.fieldNames());
/*
* Grab the key set from the second node, and see if both sets are the
* same. If not, objects are not equal, no need to check for children.
*/
final Set<String> set = Sets.newHashSet(b.fieldNames());
final Set<String> set = new HashSet<String>();
Iterator<String> iterator2 = b.fieldNames();
while (iterator2.hasNext()) {
final String next = iterator2.next();
if (next != null) {
set.add(next);
} else {
throw new NullPointerException();
}
}

if (!set.equals(keys))
return false;

Loading

0 comments on commit a381e35

Please sign in to comment.