From b8574629ea7dd0e01429d67ed2060b17e148ad7b Mon Sep 17 00:00:00 2001 From: soberich <25544967+soberich@users.noreply.github.com> Date: Fri, 30 Nov 2018 00:15:30 +0300 Subject: [PATCH] Shaded classes from Guava to keep the API stable --- project.gradle | 4 +- .../com/github/fge/jackson/JacksonUtils.java | 4 +- .../com/github/fge/jackson/JsonNumEquals.java | 69 +--- .../java/com/github/fge/jackson/NodeType.java | 4 +- .../com/google/common/base/Equivalence.java | 333 ++++++++++++++++++ .../com/google/common/base/Function.java | 64 ++++ .../common/base/FunctionalEquivalence.java | 77 ++++ .../common/base/PairwiseEquivalence.java | 79 +++++ .../com/google/common/base/Predicate.java | 62 ++++ .../fge/jackson/jsonpointer/JsonPointer.java | 8 +- .../fge/jackson/jsonpointer/TreePointer.java | 6 +- .../fge/jackson/JsonNodeReaderTest.java | 9 +- .../github/fge/jackson/JsonNumEqualsTest.java | 2 +- .../fge/jackson/SampleNodeProvider.java | 6 +- .../jsonpointer/JsonNodeResolverTest.java | 2 +- .../jackson/jsonpointer/JsonPointerTest.java | 6 +- .../jackson/jsonpointer/TreePointerTest.java | 4 +- 17 files changed, 649 insertions(+), 90 deletions(-) create mode 100644 src/main/java/com/github/fge/jackson/com/google/common/base/Equivalence.java create mode 100644 src/main/java/com/github/fge/jackson/com/google/common/base/Function.java create mode 100644 src/main/java/com/github/fge/jackson/com/google/common/base/FunctionalEquivalence.java create mode 100644 src/main/java/com/github/fge/jackson/com/google/common/base/PairwiseEquivalence.java create mode 100644 src/main/java/com/github/fge/jackson/com/google/common/base/Predicate.java diff --git a/project.gradle b/project.gradle index d93a5be..eb944d3 100644 --- a/project.gradle +++ b/project.gradle @@ -31,8 +31,8 @@ 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.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") { + implementation(group: "com.google.code.findbugs", name: "jsr305", version: "3.0.2"); + testImplementation(group: "org.testng", name: "testng", version: "7.0.0-beta1") { exclude(group: "junit", module: "junit"); exclude(group: "org.beanshell", module: "bsh"); exclude(group: "org.yaml", module: "snakeyaml"); diff --git a/src/main/java/com/github/fge/jackson/JacksonUtils.java b/src/main/java/com/github/fge/jackson/JacksonUtils.java index 85c41ff..5750d77 100644 --- a/src/main/java/com/github/fge/jackson/JacksonUtils.java +++ b/src/main/java/com/github/fge/jackson/JacksonUtils.java @@ -99,7 +99,7 @@ public static Map asMap(final JsonNode node) return Collections.emptyMap(); final Iterator> iterator = node.fields(); - final Map ret = new HashMap(); + final Map ret = new HashMap<>(); Map.Entry entry; @@ -108,7 +108,7 @@ public static Map asMap(final JsonNode node) ret.put(entry.getKey(), entry.getValue()); } - return ret; + return Collections.unmodifiableMap(ret); } /** diff --git a/src/main/java/com/github/fge/jackson/JsonNumEquals.java b/src/main/java/com/github/fge/jackson/JsonNumEquals.java index f098d4b..e061c8e 100644 --- a/src/main/java/com/github/fge/jackson/JsonNumEquals.java +++ b/src/main/java/com/github/fge/jackson/JsonNumEquals.java @@ -20,8 +20,8 @@ package com.github.fge.jackson; import com.fasterxml.jackson.databind.JsonNode; +import com.github.fge.jackson.com.google.common.base.Equivalence; -import javax.annotation.Nullable; import java.util.HashSet; import java.util.Iterator; import java.util.Map; @@ -41,50 +41,21 @@ * kind of equality.

*/ public final class JsonNumEquals + extends Equivalence { - private static final JsonNumEquals INSTANCE + private static final Equivalence INSTANCE = new JsonNumEquals(); private JsonNumEquals() { } - public static JsonNumEquals getInstance() + public static Equivalence getInstance() { return INSTANCE; } - /** - * Returns {@code true} if the given objects are considered equivalent. - * - *

The {@code equivalent} method implements an equivalence relation on object references: - * - *

    - *
  • It is reflexive: for any reference {@code x}, including null, {@code - * equivalent(x, x)} returns {@code true}. - *
  • It is symmetric: for any references {@code x} and {@code y}, {@code - * equivalent(x, y) == equivalent(y, x)}. - *
  • It is transitive: 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}. - *
  • It is consistent: 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). - *
- * @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); - } - + @Override protected boolean doEquivalent(final JsonNode a, final JsonNode b) { /* @@ -122,31 +93,7 @@ protected boolean doEquivalent(final JsonNode a, final JsonNode b) return typeA == NodeType.ARRAY ? arrayEquals(a, b) : objectEquals(a, b); } - /** - * Returns a hash code for {@code t}. - * - *

The {@code hash} has the following properties: - *

    - *
  • It is consistent: 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. - *
  • It is distributable across equivalence: for any references {@code x} and {@code y}, - * if {@code equivalent(x, y)}, then {@code hash(x) == hash(y)}. It is not necessary - * that the hash be distributable across inequivalence. If {@code equivalence(x, y)} - * is false, {@code hash(x) == hash(y)} may still be true. - *
  • {@code hash(null)} is {@code 0}. - *
- * @param t node to hash - * @return hash - */ - public final int hash(@Nullable JsonNode t) { - if (t == null) { - return 0; - } - return doHash(t); - } - + @Override protected int doHash(final JsonNode t) { /* @@ -236,7 +183,7 @@ private boolean objectEquals(final JsonNode a, final JsonNode b) /* * Grab the key set from the first node */ - final Set keys = new HashSet(); + final Set keys = new HashSet<>(); Iterator iterator1 = a.fieldNames(); while (iterator1.hasNext()) { final String next = iterator1.next(); @@ -251,7 +198,7 @@ private boolean objectEquals(final JsonNode a, final JsonNode b) * 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 set = new HashSet(); + final Set set = new HashSet<>(); Iterator iterator2 = b.fieldNames(); while (iterator2.hasNext()) { final String next = iterator2.next(); diff --git a/src/main/java/com/github/fge/jackson/NodeType.java b/src/main/java/com/github/fge/jackson/NodeType.java index ea15551..67ddf86 100644 --- a/src/main/java/com/github/fge/jackson/NodeType.java +++ b/src/main/java/com/github/fge/jackson/NodeType.java @@ -86,7 +86,7 @@ public enum NodeType * #getNodeType(JsonNode)}) */ private static final Map TOKEN_MAP - = new EnumMap(JsonToken.class); + = new EnumMap<>(JsonToken.class); static { TOKEN_MAP.put(JsonToken.START_ARRAY, ARRAY); @@ -99,7 +99,7 @@ public enum NodeType TOKEN_MAP.put(JsonToken.VALUE_STRING, STRING); final Map builder - = new HashMap(); + = new HashMap<>(); for (final NodeType type: NodeType.values()) builder.put(type.name, type); diff --git a/src/main/java/com/github/fge/jackson/com/google/common/base/Equivalence.java b/src/main/java/com/github/fge/jackson/com/google/common/base/Equivalence.java new file mode 100644 index 0000000..11633dc --- /dev/null +++ b/src/main/java/com/github/fge/jackson/com/google/common/base/Equivalence.java @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2010 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.github.fge.jackson.com.google.common.base; + +import javax.annotation.Nullable; +import java.io.Serializable; +import java.util.Arrays; + +/** + * A strategy for determining whether two instances are considered equivalent. Examples of + * equivalences are the {@linkplain #identity() identity equivalence} and {@linkplain #equals equals + * equivalence}. + * + * @author Bob Lee + * @author Ben Yu + * @author Gregory Kick + * @author soberich on 29-Nov-18 + */ +public abstract class Equivalence { + /** + * Constructor for use by subclasses. + */ + protected Equivalence() {} + + /** + * Returns {@code true} if the given objects are considered equivalent. + * + *

The {@code equivalent} method implements an equivalence relation on object references: + * + *

    + *
  • It is reflexive: for any reference {@code x}, including null, {@code + * equivalent(x, x)} returns {@code true}. + *
  • It is symmetric: for any references {@code x} and {@code y}, {@code + * equivalent(x, y) == equivalent(y, x)}. + *
  • It is transitive: 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}. + *
  • It is consistent: 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). + *
+ */ + public final boolean equivalent(@Nullable T a, @Nullable T b) { + if (a == b) { + return true; + } + if (a == null || b == null) { + return false; + } + return doEquivalent(a, b); + } + + /** + * Returns {@code true} if {@code a} and {@code b} are considered equivalent. + * + *

Called by {@link #equivalent}. {@code a} and {@code b} are not the same + * object and are not nulls. + */ + protected abstract boolean doEquivalent(T a, T b); + + /** + * Returns a hash code for {@code t}. + * + *

The {@code hash} has the following properties: + *

    + *
  • It is consistent: 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. + *
  • It is distributable across equivalence: for any references {@code x} and {@code y}, + * if {@code equivalent(x, y)}, then {@code hash(x) == hash(y)}. It is not necessary + * that the hash be distributable across inequivalence. If {@code equivalence(x, y)} + * is false, {@code hash(x) == hash(y)} may still be true. + *
  • {@code hash(null)} is {@code 0}. + *
+ */ + public final int hash(@Nullable T t) { + if (t == null) { + return 0; + } + return doHash(t); + } + + /** + * Returns a hash code for non-null object {@code t}. + * + *

Called by {@link #hash}. + */ + protected abstract int doHash(T t); + + /** + * Returns a new equivalence relation for {@code F} which evaluates equivalence by first applying + * {@code function} to the argument, then evaluating using {@code this}. That is, for any pair of + * non-null objects {@code x} and {@code y}, {@code + * equivalence.onResultOf(function).equivalent(a, b)} is true if and only if {@code + * equivalence.equivalent(function.apply(a), function.apply(b))} is true. + * + *

For example: + * + *

   {@code
+     *    Equivalence SAME_AGE = Equivalence.equals().onResultOf(GET_PERSON_AGE);}
+ * + *

{@code function} will never be invoked with a null value. + * + *

Note that {@code function} must be consistent according to {@code this} equivalence + * relation. That is, invoking {@code com.google.common.base.Function#apply} multiple times for a given value must return + * equivalent results. + * For example, {@code Equivalence.identity().onResultOf(Functions.toStringFunction())} is broken + * because it's not guaranteed that {@link Object#toString}) always returns the same string + * instance. + */ + public final Equivalence onResultOf(Function function) { + return new FunctionalEquivalence<>(function, this); + } + + /** + * Returns a wrapper of {@code reference} that implements + * {@link Wrapper#equals(Object) Object.equals()} such that + * {@code wrap(a).equals(wrap(b))} if and only if {@code equivalent(a, b)}. + */ + public final Wrapper wrap(@Nullable S reference) { + return new Wrapper(this, reference); + } + + /** + * Wraps an object so that {@link #equals(Object)} and {@link #hashCode()} delegate to an + * {@link Equivalence}. + * + *

For example, given an {@link Equivalence} for {@link String strings} named {@code equiv} + * that tests equivalence using their lengths: + * + *

   {@code
+     *   equiv.wrap("a").equals(equiv.wrap("b")) // true
+     *   equiv.wrap("a").equals(equiv.wrap("hello")) // false}
+ * + *

Note in particular that an equivalence wrapper is never equal to the object it wraps. + * + *

   {@code
+     *   equiv.wrap(obj).equals(obj) // always false}
+ */ + public static final class Wrapper implements Serializable { + private final Equivalence equivalence; + @Nullable private final T reference; + + private Wrapper(Equivalence equivalence, @Nullable T reference) { + if (equivalence == null) { + throw new NullPointerException(); + } + this.equivalence = equivalence; + this.reference = reference; + } + + /** Returns the (possibly null) reference wrapped by this instance. */ + @Nullable public T get() { + return reference; + } + + /** + * Returns {@code true} if {@link Equivalence#equivalent(Object, Object)} applied to the wrapped + * references is {@code true} and both wrappers use the {@link Object#equals(Object) same} + * equivalence. + */ + @Override public boolean equals(@Nullable Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof Wrapper) { + Wrapper that = (Wrapper) obj; // note: not necessarily a Wrapper + + if (this.equivalence.equals(that.equivalence)) { + /* + * We'll accept that as sufficient "proof" that either equivalence should be able to + * handle either reference, so it's safe to circumvent compile-time type checking. + */ + @SuppressWarnings("unchecked") + Equivalence equivalence = (Equivalence) this.equivalence; + return equivalence.equivalent(this.reference, that.reference); + } + } + return false; + } + + /** + * Returns the result of {@link Equivalence#hash(Object)} applied to the wrapped reference. + */ + @Override public int hashCode() { + return equivalence.hash(reference); + } + + /** + * Returns a string representation for this equivalence wrapper. The form of this string + * representation is not specified. + */ + @Override public String toString() { + return equivalence + ".wrap(" + reference + ")"; + } + + private static final long serialVersionUID = 0; + } + + /** + * Returns an equivalence over iterables based on the equivalence of their elements. More + * specifically, two iterables are considered equivalent if they both contain the same number of + * elements, and each pair of corresponding elements is equivalent according to + * {@code this}. Null iterables are equivalent to one another. + * + *

Note that this method performs a similar function for equivalences as {@code + * com.google.common.collect.Ordering#lexicographical} does for orderings. + */ + public final Equivalence> pairwise() { + // Ideally, the returned equivalence would support Iterable. However, + // the need for this is so rare that it's not worth making callers deal with the ugly wildcard. + return new PairwiseEquivalence<>(this); + } + + /** + * Returns a predicate that evaluates to true if and only if the input is + * equivalent to {@code target} according to this equivalence relation. + */ + public final Predicate equivalentTo(@Nullable T target) { + return new EquivalentToPredicate<>(this, target); + } + + private static final class EquivalentToPredicate implements Predicate, Serializable { + + private final Equivalence equivalence; + @Nullable private final T target; + + EquivalentToPredicate(Equivalence equivalence, @Nullable T target) { + if (equivalence == null) { + throw new NullPointerException(); + } + this.equivalence = equivalence; + this.target = target; + } + + @Override public boolean apply(@Nullable T input) { + return equivalence.equivalent(input, target); + } + + @Override public boolean equals(@Nullable Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof EquivalentToPredicate) { + EquivalentToPredicate that = (EquivalentToPredicate) obj; + return (equivalence.equals(that.equivalence) + && (target == that.target)) || ((target != null) && target.equals(that.target)); + } + return false; + } + + @Override public int hashCode() { + return Arrays.hashCode(new Object[]{equivalence, target}); + } + + @Override public String toString() { + return equivalence + ".equivalentTo(" + target + ")"; + } + + private static final long serialVersionUID = 0; + } + + /** + * Returns an equivalence that delegates to {@link Object#equals} and {@link Object#hashCode}. + * {@link Equivalence#equivalent} returns {@code true} if both values are null, or if neither + * value is null and {@link Object#equals} returns {@code true}. {@link Equivalence#hash} returns + * {@code 0} if passed a null value. + */ + public static Equivalence equals() { + return Equals.INSTANCE; + } + + /** + * Returns an equivalence that uses {@code ==} to compare values and {@link + * System#identityHashCode(Object)} to compute the hash code. {@link Equivalence#equivalent} + * returns {@code true} if {@code a == b}, including in the case that a and b are both null. + */ + public static Equivalence identity() { + return Identity.INSTANCE; + } + + static final class Equals extends Equivalence + implements Serializable { + + static final Equals INSTANCE = new Equals(); + + @Override protected boolean doEquivalent(Object a, Object b) { + return a.equals(b); + } + @Override public int doHash(Object o) { + return o.hashCode(); + } + + private Object readResolve() { + return INSTANCE; + } + private static final long serialVersionUID = 1; + } + + static final class Identity extends Equivalence + implements Serializable { + + static final Identity INSTANCE = new Identity(); + + @Override protected boolean doEquivalent(Object a, Object b) { + return false; + } + + @Override protected int doHash(Object o) { + return System.identityHashCode(o); + } + + private Object readResolve() { + return INSTANCE; + } + private static final long serialVersionUID = 1; + } +} diff --git a/src/main/java/com/github/fge/jackson/com/google/common/base/Function.java b/src/main/java/com/github/fge/jackson/com/google/common/base/Function.java new file mode 100644 index 0000000..fb53cd2 --- /dev/null +++ b/src/main/java/com/github/fge/jackson/com/google/common/base/Function.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2007 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.github.fge.jackson.com.google.common.base; + +import javax.annotation.Nullable; + +/** + * Determines an output value based on an input value. + * + *

The {@code com.google.common.base.Functions} class provides common functions and related utilites. + * + *

See the Guava User Guide article on the use of {@code + * Function}. + * + * @author Kevin Bourrillion + * @author soberich on 29-Nov-18 + * @since 1.10 (imported from Google Collections Library) + */ +public interface Function { + /** + * Returns the result of applying this function to {@code input}. This method is generally + * expected, but not absolutely required, to have the following properties: + * + *

    + *
  • Its execution does not cause any observable side effects. + *
  • The computation is consistent with equals; that is, {@code com.google.common.base.Objects#equal + * Objects.equal}{@code (a, b)} implies that {@code Objects.equal(function.apply(a), + * function.apply(b))}. + *
+ * + * @throws NullPointerException if {@code input} is null and this function does not accept null + * arguments + */ + @Nullable + T apply(@Nullable F input); + + /** + * Indicates whether another object is equal to this function. + * + *

Most implementations will have no reason to override the behavior of {@link Object#equals}. + * However, an implementation may also choose to return {@code true} whenever {@code object} is a + * {@link Function} that it considers interchangeable with this one. "Interchangeable" + * typically means that {@code Objects.equal(this.apply(f), that.apply(f))} is true for all + * {@code f} of type {@code F}. Note that a {@code false} result from this method does not imply + * that the functions are known not to be interchangeable. + */ + @Override + boolean equals(@Nullable Object object); +} diff --git a/src/main/java/com/github/fge/jackson/com/google/common/base/FunctionalEquivalence.java b/src/main/java/com/github/fge/jackson/com/google/common/base/FunctionalEquivalence.java new file mode 100644 index 0000000..423a096 --- /dev/null +++ b/src/main/java/com/github/fge/jackson/com/google/common/base/FunctionalEquivalence.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2011 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.github.fge.jackson.com.google.common.base; + +import javax.annotation.Nullable; +import java.io.Serializable; +import java.util.Arrays; + +/** + * Equivalence applied on functional result. + * + * @author Bob Lee + * @author soberich on 29-Nov-18 + * @since 1.10 + */ +final class FunctionalEquivalence extends Equivalence + implements Serializable { + + private static final long serialVersionUID = 0; + + private final Function function; + private final Equivalence resultEquivalence; + + FunctionalEquivalence( + Function function, Equivalence resultEquivalence) { + if (function == null) { + throw new NullPointerException(); + } + this.function = function; + if (resultEquivalence == null) { + throw new NullPointerException(); + } + this.resultEquivalence = resultEquivalence; + } + + @Override protected boolean doEquivalent(F a, F b) { + return resultEquivalence.equivalent(function.apply(a), function.apply(b)); + } + + @Override protected int doHash(F a) { + return resultEquivalence.hash(function.apply(a)); + } + + @Override public boolean equals(@Nullable Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof FunctionalEquivalence) { + FunctionalEquivalence that = (FunctionalEquivalence) obj; + return function.equals(that.function) + && resultEquivalence.equals(that.resultEquivalence); + } + return false; + } + + @Override public int hashCode() { + return Arrays.hashCode(new Object[]{function, resultEquivalence}); + } + + @Override public String toString() { + return resultEquivalence + ".onResultOf(" + function + ")"; + } +} diff --git a/src/main/java/com/github/fge/jackson/com/google/common/base/PairwiseEquivalence.java b/src/main/java/com/github/fge/jackson/com/google/common/base/PairwiseEquivalence.java new file mode 100644 index 0000000..d1d2f19 --- /dev/null +++ b/src/main/java/com/github/fge/jackson/com/google/common/base/PairwiseEquivalence.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2011 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.github.fge.jackson.com.google.common.base; + +import javax.annotation.Nullable; +import java.io.Serializable; +import java.util.Iterator; + +final class PairwiseEquivalence extends Equivalence> + implements Serializable { + + final Equivalence elementEquivalence; + + PairwiseEquivalence(Equivalence elementEquivalence) { + if (elementEquivalence == null) { + throw new NullPointerException(); + } + this.elementEquivalence = elementEquivalence; + } + + @Override + protected boolean doEquivalent(Iterable iterableA, Iterable iterableB) { + Iterator iteratorA = iterableA.iterator(); + Iterator iteratorB = iterableB.iterator(); + + while (iteratorA.hasNext() && iteratorB.hasNext()) { + if (!elementEquivalence.equivalent(iteratorA.next(), iteratorB.next())) { + return false; + } + } + + return !iteratorA.hasNext() && !iteratorB.hasNext(); + } + + @Override + protected int doHash(Iterable iterable) { + int hash = 78721; + for (T element : iterable) { + hash = hash * 24943 + elementEquivalence.hash(element); + } + return hash; + } + + @Override + public boolean equals(@Nullable Object object) { + if (object instanceof PairwiseEquivalence) { + PairwiseEquivalence that = (PairwiseEquivalence) object; + return this.elementEquivalence.equals(that.elementEquivalence); + } + + return false; + } + + @Override + public int hashCode() { + return elementEquivalence.hashCode() ^ 0x46a3eb07; + } + + @Override + public String toString() { + return elementEquivalence + ".pairwise()"; + } + + private static final long serialVersionUID = 1; +} diff --git a/src/main/java/com/github/fge/jackson/com/google/common/base/Predicate.java b/src/main/java/com/github/fge/jackson/com/google/common/base/Predicate.java new file mode 100644 index 0000000..6ffa6d0 --- /dev/null +++ b/src/main/java/com/github/fge/jackson/com/google/common/base/Predicate.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2007 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.github.fge.jackson.com.google.common.base; + +import javax.annotation.Nullable; + +/** + * Determines a true or false value for a given input. + * + *

The {@code com.google.common.base.Predicates} class provides common predicates and related utilities. + * + *

See the Guava User Guide article on the use of {@code + * Predicate}. + * + * @author Kevin Bourrillion + * @since 2.0 (imported from Google Collections Library) + */ +public interface Predicate { + /** + * Returns the result of applying this predicate to {@code input}. This method is generally + * expected, but not absolutely required, to have the following properties: + * + *

    + *
  • Its execution does not cause any observable side effects. + *
  • The computation is consistent with equals; that is, {@code com.google.common.base.Objects#equal + * Objects.equal}{@code (a, b)} implies that {@code predicate.apply(a) == + * predicate.apply(b))}. + *
+ * + * @throws NullPointerException if {@code input} is null and this predicate does not accept null + * arguments + */ + boolean apply(@Nullable T input); + + /** + * Indicates whether another object is equal to this predicate. + * + *

Most implementations will have no reason to override the behavior of {@link Object#equals}. + * However, an implementation may also choose to return {@code true} whenever {@code object} is a + * {@link Predicate} that it considers interchangeable with this one. "Interchangeable" + * typically means that {@code this.apply(t) == that.apply(t)} for all {@code t} of type + * {@code T}). Note that a {@code false} result from this method does not imply that the + * predicates are known not to be interchangeable. + */ + @Override + boolean equals(@Nullable Object object); +} diff --git a/src/main/java/com/github/fge/jackson/jsonpointer/JsonPointer.java b/src/main/java/com/github/fge/jackson/jsonpointer/JsonPointer.java index 670e50b..0aae6a5 100644 --- a/src/main/java/com/github/fge/jackson/jsonpointer/JsonPointer.java +++ b/src/main/java/com/github/fge/jackson/jsonpointer/JsonPointer.java @@ -72,7 +72,7 @@ public static JsonPointer empty() */ public static JsonPointer of(final Object first, final Object... other) { - final List tokens = new ArrayList(); + final List tokens = new ArrayList<>(); tokens.add(ReferenceToken.fromRaw(first.toString())); @@ -120,7 +120,7 @@ public JsonPointer append(final String raw) final ReferenceToken refToken = ReferenceToken.fromRaw(raw); final JsonNodeResolver resolver = new JsonNodeResolver(refToken); final List> list - = new ArrayList>(); + = new ArrayList<>(); for (final TokenResolver tokenResolver : tokenResolvers) { if (tokenResolver != null) { list.add(tokenResolver); @@ -154,7 +154,7 @@ public JsonPointer append(final JsonPointer other) { BUNDLE.checkNotNull(other, "nullInput"); final List> list - = new ArrayList>(); + = new ArrayList<>(); for (final TokenResolver tokenResolver : tokenResolvers) { if (tokenResolver != null) { list.add(tokenResolver); @@ -191,7 +191,7 @@ public JsonPointer parent() private static List> fromTokens( final List tokens) { - final List> list = new ArrayList>(); + final List> list = new ArrayList<>(); for (final ReferenceToken token: tokens) list.add(new JsonNodeResolver(token)); return list; diff --git a/src/main/java/com/github/fge/jackson/jsonpointer/TreePointer.java b/src/main/java/com/github/fge/jackson/jsonpointer/TreePointer.java index df82ef8..8d6daee 100644 --- a/src/main/java/com/github/fge/jackson/jsonpointer/TreePointer.java +++ b/src/main/java/com/github/fge/jackson/jsonpointer/TreePointer.java @@ -92,7 +92,7 @@ protected TreePointer(final T missing, final List> tokenResolvers) { this.missing = missing; - this.tokenResolvers = Collections.unmodifiableList(new ArrayList>(tokenResolvers)); + this.tokenResolvers = Collections.unmodifiableList(new ArrayList<>(tokenResolvers)); } /** @@ -174,7 +174,7 @@ public final boolean equals(final Object obj) return false; if (this == obj) return true; - if (getClass() != obj.getClass()) + if (!(obj instanceof TreePointer)) return false; final TreePointer other = (TreePointer) obj; return tokenResolvers.equals(other.tokenResolvers); @@ -206,7 +206,7 @@ protected static List tokensFromInput(final String input) throws JsonPointerException { String s = BUNDLE.checkNotNull(input, "nullInput"); - final List ret = new ArrayList(); + final List ret = new ArrayList<>(); String cooked; int index; char c; diff --git a/src/test/java/com/github/fge/jackson/JsonNodeReaderTest.java b/src/test/java/com/github/fge/jackson/JsonNodeReaderTest.java index 7a60cd4..2965822 100644 --- a/src/test/java/com/github/fge/jackson/JsonNodeReaderTest.java +++ b/src/test/java/com/github/fge/jackson/JsonNodeReaderTest.java @@ -33,6 +33,7 @@ import java.io.Reader; import java.io.StringReader; import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -70,7 +71,7 @@ public void readerIsClosedOnRead() @DataProvider public Iterator getMalformedData() { - final List list = new ArrayList(); + final List list = new ArrayList<>(); list.add(new Object[] { "", "read.noContent"}); list.add(new Object[] { "[]{}", "read.trailingData"}); @@ -104,11 +105,7 @@ private static Supplier provideInputStream(final String input) @Override public InputStream get() { - try { - return new ByteArrayInputStream(input.getBytes("UTF-8")); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException("Unhandled exception", e); - } + return new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8)); } }; } diff --git a/src/test/java/com/github/fge/jackson/JsonNumEqualsTest.java b/src/test/java/com/github/fge/jackson/JsonNumEqualsTest.java index cecb942..af4d068 100644 --- a/src/test/java/com/github/fge/jackson/JsonNumEqualsTest.java +++ b/src/test/java/com/github/fge/jackson/JsonNumEqualsTest.java @@ -49,7 +49,7 @@ public void initData() @DataProvider public Iterator getInputs() { - final List list = new ArrayList(); + final List list = new ArrayList<>(); JsonNode reference; diff --git a/src/test/java/com/github/fge/jackson/SampleNodeProvider.java b/src/test/java/com/github/fge/jackson/SampleNodeProvider.java index ec03e32..23817f7 100644 --- a/src/test/java/com/github/fge/jackson/SampleNodeProvider.java +++ b/src/test/java/com/github/fge/jackson/SampleNodeProvider.java @@ -35,7 +35,7 @@ private SampleNodeProvider() } static { - SAMPLE_DATA = new EnumMap(NodeType.class); + SAMPLE_DATA = new EnumMap<>(NodeType.class); SAMPLE_DATA.put(NodeType.ARRAY, FACTORY.arrayNode()); SAMPLE_DATA.put(NodeType.BOOLEAN, FACTORY.booleanNode(true)); @@ -52,10 +52,10 @@ private SampleNodeProvider() // differ... public static Iterator getSamples(final EnumSet types) { - final Map map = new EnumMap(SAMPLE_DATA); + final Map map = new EnumMap<>(SAMPLE_DATA); map.keySet().retainAll(types); - final ArrayList samples = new ArrayList(); + final List samples = new ArrayList<>(); for (final JsonNode input : map.values()) { samples.add(new Object[] { input }); } diff --git a/src/test/java/com/github/fge/jackson/jsonpointer/JsonNodeResolverTest.java b/src/test/java/com/github/fge/jackson/jsonpointer/JsonNodeResolverTest.java index d4a042f..6f22fda 100644 --- a/src/test/java/com/github/fge/jackson/jsonpointer/JsonNodeResolverTest.java +++ b/src/test/java/com/github/fge/jackson/jsonpointer/JsonNodeResolverTest.java @@ -104,7 +104,7 @@ public void resolvingArrayIndicesWorks() @DataProvider public Iterator invalidIndices() { - final List list = new ArrayList(); + final List list = new ArrayList<>(); list.add(new Object[] { "-1" }); list.add(new Object[] { "232398087298731987987232" }); diff --git a/src/test/java/com/github/fge/jackson/jsonpointer/JsonPointerTest.java b/src/test/java/com/github/fge/jackson/jsonpointer/JsonPointerTest.java index c04fded..be19a61 100644 --- a/src/test/java/com/github/fge/jackson/jsonpointer/JsonPointerTest.java +++ b/src/test/java/com/github/fge/jackson/jsonpointer/JsonPointerTest.java @@ -66,7 +66,7 @@ public void cannotAppendNullPointer() @DataProvider public Iterator rawPointers() { - final List list = new ArrayList(); + final List list = new ArrayList<>(); final JsonNode testNode = testData.get("pointers"); final Map map = JacksonUtils.asMap(testNode); @@ -89,7 +89,7 @@ public void rawPointerResolvingWorks(final String input, @DataProvider public Iterator uriPointers() { - final List list = new ArrayList(); + final List list = new ArrayList<>(); final JsonNode testNode = testData.get("uris"); final Map map = JacksonUtils.asMap(testNode); @@ -181,7 +181,7 @@ public void staticConstructionFromTokensWorks() @DataProvider public Iterator parentTestData() { - final List list = new ArrayList(); + final List list = new ArrayList<>(); // Empty list.add(new Object[] { JsonPointer.empty(), JsonPointer.empty() }); diff --git a/src/test/java/com/github/fge/jackson/jsonpointer/TreePointerTest.java b/src/test/java/com/github/fge/jackson/jsonpointer/TreePointerTest.java index a42a406..2edc050 100644 --- a/src/test/java/com/github/fge/jackson/jsonpointer/TreePointerTest.java +++ b/src/test/java/com/github/fge/jackson/jsonpointer/TreePointerTest.java @@ -154,7 +154,7 @@ public void gettingPathOfMissingNodeReturnsMissingNode() @Test public void treePointerCanTellWhetherItIsEmpty() { - final List> list = new ArrayList>(); + final List> list = new ArrayList<>(); assertTrue(new DummyPointer(null, list).isEmpty()); @@ -168,7 +168,7 @@ public void treePointerCanTellWhetherItIsEmpty() @Test public void treeIsUnalteredWhenOriginalListIsAltered() { - final List> list = new ArrayList>(); + final List> list = new ArrayList<>(); final DummyPointer dummy = new DummyPointer(null, list); @SuppressWarnings("unchecked")