From ce784a608a6075f41370e37cf7791ae72b362f1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louise=20S=C3=B6derstr=C3=B6m?= Date: Mon, 12 Sep 2022 11:32:35 +0200 Subject: [PATCH 1/9] Copy over Pair helper from Neo4j To reduce dependencies of internal APIs --- .../main/java/apoc/algo/PathFindingUtils.java | 2 +- .../path/RelationshipTypeAndDirections.java | 2 +- .../java/apoc/periodic/PeriodicUtils.java | 2 +- .../java/apoc/trigger/TriggerHandler.java | 2 +- common/src/main/java/apoc/util/Util.java | 2 +- .../main/java/apoc/util/collection/Pair.java | 85 +++++++++++++++++++ .../RelationshipTypeAndDirectionsTest.java | 2 +- core/src/main/java/apoc/coll/Coll.java | 2 +- core/src/main/java/apoc/meta/Meta.java | 2 +- .../main/java/apoc/neighbors/Neighbors.java | 2 +- core/src/main/java/apoc/nodes/Nodes.java | 3 +- .../path/RelationshipSequenceExpander.java | 2 +- .../src/main/java/apoc/periodic/Periodic.java | 2 +- .../java/apoc/refactor/util/RefactorUtil.java | 2 +- .../java/apoc/stats/DegreeDistribution.java | 2 +- core/src/main/java/apoc/text/Strings.java | 2 +- .../java/apoc/periodic/PeriodicUtilsTest.java | 2 +- core/src/test/java/apoc/util/UtilTest.java | 2 +- test-utils/build.gradle | 1 + .../apoc/util/SensitivePathGenerator.java | 2 +- 20 files changed, 104 insertions(+), 19 deletions(-) create mode 100644 common/src/main/java/apoc/util/collection/Pair.java diff --git a/common/src/main/java/apoc/algo/PathFindingUtils.java b/common/src/main/java/apoc/algo/PathFindingUtils.java index 4aa9969dc..c44f33043 100644 --- a/common/src/main/java/apoc/algo/PathFindingUtils.java +++ b/common/src/main/java/apoc/algo/PathFindingUtils.java @@ -1,13 +1,13 @@ package apoc.algo; import apoc.path.RelationshipTypeAndDirections; +import apoc.util.collection.Pair; import org.neo4j.graphalgo.EstimateEvaluator; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.PathExpander; import org.neo4j.graphdb.PathExpanderBuilder; import org.neo4j.graphdb.RelationshipType; -import org.neo4j.internal.helpers.collection.Pair; import org.neo4j.values.storable.PointValue; public class PathFindingUtils { diff --git a/common/src/main/java/apoc/path/RelationshipTypeAndDirections.java b/common/src/main/java/apoc/path/RelationshipTypeAndDirections.java index ff49ca0ea..e353cd817 100644 --- a/common/src/main/java/apoc/path/RelationshipTypeAndDirections.java +++ b/common/src/main/java/apoc/path/RelationshipTypeAndDirections.java @@ -1,8 +1,8 @@ package apoc.path; +import apoc.util.collection.Pair; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.RelationshipType; -import org.neo4j.internal.helpers.collection.Pair; import java.util.ArrayList; import java.util.List; diff --git a/common/src/main/java/apoc/periodic/PeriodicUtils.java b/common/src/main/java/apoc/periodic/PeriodicUtils.java index 4c889138d..22492b65a 100644 --- a/common/src/main/java/apoc/periodic/PeriodicUtils.java +++ b/common/src/main/java/apoc/periodic/PeriodicUtils.java @@ -1,12 +1,12 @@ package apoc.periodic; import apoc.Pools; +import apoc.util.collection.Pair; import apoc.util.Util; import org.apache.commons.lang3.exception.ExceptionUtils; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.QueryStatistics; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Pair; import org.neo4j.logging.Log; import org.neo4j.procedure.TerminationGuard; diff --git a/common/src/main/java/apoc/trigger/TriggerHandler.java b/common/src/main/java/apoc/trigger/TriggerHandler.java index a96ee19ea..84f2cd65b 100644 --- a/common/src/main/java/apoc/trigger/TriggerHandler.java +++ b/common/src/main/java/apoc/trigger/TriggerHandler.java @@ -4,6 +4,7 @@ import apoc.Pools; import apoc.SystemLabels; import apoc.SystemPropertyKeys; +import apoc.util.collection.Pair; import apoc.util.Util; import org.neo4j.dbms.api.DatabaseManagementService; import org.neo4j.function.ThrowingFunction; @@ -15,7 +16,6 @@ import org.neo4j.graphdb.event.TransactionEventListener; import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.internal.helpers.collection.MapUtil; -import org.neo4j.internal.helpers.collection.Pair; import org.neo4j.internal.kernel.api.exceptions.ProcedureException; import org.neo4j.kernel.api.procedure.Context; import org.neo4j.kernel.api.procedure.GlobalProcedures; diff --git a/common/src/main/java/apoc/util/Util.java b/common/src/main/java/apoc/util/Util.java index 79796ed76..54046ad68 100644 --- a/common/src/main/java/apoc/util/Util.java +++ b/common/src/main/java/apoc/util/Util.java @@ -7,6 +7,7 @@ import apoc.export.util.ExportConfig; import apoc.result.VirtualNode; import apoc.result.VirtualRelationship; +import apoc.util.collection.Pair; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveInputStream; import org.apache.commons.io.IOUtils; @@ -89,7 +90,6 @@ import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.TransactionTerminatedException; import org.neo4j.internal.helpers.collection.Iterators; -import org.neo4j.internal.helpers.collection.Pair; import org.neo4j.internal.kernel.api.procs.ProcedureCallContext; import org.neo4j.internal.kernel.api.security.SecurityContext; import org.neo4j.kernel.internal.GraphDatabaseAPI; diff --git a/common/src/main/java/apoc/util/collection/Pair.java b/common/src/main/java/apoc/util/collection/Pair.java new file mode 100644 index 000000000..641aac260 --- /dev/null +++ b/common/src/main/java/apoc/util/collection/Pair.java @@ -0,0 +1,85 @@ +package apoc.util.collection; + +import java.util.Objects; + +/** + * Utility to handle pairs of objects. + * + * @param the type of the {@link #first() first value} of the pair. + * @param the type of the {@link #other() other value} of the pair. + */ +public abstract class Pair { + /** + * Create a new pair of objects. + * + * @param first the first object in the pair. + * @param other the other object in the pair. + * @param the type of the first object in the pair + * @param the type of the second object in the pair + * @return a new pair of the two parameters. + */ + public static Pair pair(final T1 first, final T2 other) { + return new Pair<>() { + @Override + public T1 first() { + return first; + } + + @Override + public T2 other() { + return other; + } + }; + } + + /** + * Alias of {@link #pair(Object, Object)}. + * @param first the first object in the pair. + * @param other the other object in the pair. + * @param the type of the first object in the pair + * @param the type of the second object in the pair + * @return a new pair of the two parameters. + */ + public static Pair of(final T1 first, final T2 other) { + return pair(first, other); + } + + Pair() { + // package private, limited number of subclasses + } + + /** + * @return the first object in the pair. + */ + public abstract T1 first(); + + /** + * @return the other object in the pair. + */ + public abstract T2 other(); + + @Override + public String toString() { + return "(" + first() + ", " + other() + ")"; + } + + @Override + public int hashCode() { + return (31 * hashCode(first())) | hashCode(other()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof Pair that) { + return Objects.equals(this.other(), that.other()) && Objects.equals(this.first(), that.first()); + } + return false; + } + + private static int hashCode(Object obj) { + return obj == null ? 0 : obj.hashCode(); + } +} diff --git a/common/src/test/java/apoc/path/RelationshipTypeAndDirectionsTest.java b/common/src/test/java/apoc/path/RelationshipTypeAndDirectionsTest.java index 5a5c1b672..f7baecd9c 100644 --- a/common/src/test/java/apoc/path/RelationshipTypeAndDirectionsTest.java +++ b/common/src/test/java/apoc/path/RelationshipTypeAndDirectionsTest.java @@ -1,5 +1,6 @@ package apoc.path; +import apoc.util.collection.Pair; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -7,7 +8,6 @@ import org.junit.runners.Parameterized.Parameters; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.RelationshipType; -import org.neo4j.internal.helpers.collection.Pair; import java.util.Arrays; diff --git a/core/src/main/java/apoc/coll/Coll.java b/core/src/main/java/apoc/coll/Coll.java index ba83bf292..00ee40efc 100644 --- a/core/src/main/java/apoc/coll/Coll.java +++ b/core/src/main/java/apoc/coll/Coll.java @@ -1,6 +1,7 @@ package apoc.coll; import apoc.result.ListResult; +import apoc.util.collection.Pair; import com.google.common.util.concurrent.AtomicDouble; import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.math3.stat.descriptive.moment.StandardDeviation; @@ -11,7 +12,6 @@ import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.Result; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Pair; import org.neo4j.procedure.Context; import org.neo4j.procedure.Description; import org.neo4j.procedure.Name; diff --git a/core/src/main/java/apoc/meta/Meta.java b/core/src/main/java/apoc/meta/Meta.java index 3b4622903..f88b6bd4a 100644 --- a/core/src/main/java/apoc/meta/Meta.java +++ b/core/src/main/java/apoc/meta/Meta.java @@ -7,6 +7,7 @@ import apoc.result.VirtualNode; import apoc.result.VirtualRelationship; import apoc.util.MapUtil; +import apoc.util.collection.Pair; import org.apache.commons.collections4.CollectionUtils; import org.neo4j.cypher.export.CypherResultSubGraph; import org.neo4j.cypher.export.DatabaseSubGraph; @@ -27,7 +28,6 @@ import org.neo4j.graphdb.schema.IndexDefinition; import org.neo4j.graphdb.schema.Schema; import org.neo4j.internal.helpers.collection.Iterables; -import org.neo4j.internal.helpers.collection.Pair; import org.neo4j.internal.kernel.api.Read; import org.neo4j.internal.kernel.api.TokenRead; import org.neo4j.kernel.api.KernelTransaction; diff --git a/core/src/main/java/apoc/neighbors/Neighbors.java b/core/src/main/java/apoc/neighbors/Neighbors.java index d805a643d..c0e0c3bcc 100644 --- a/core/src/main/java/apoc/neighbors/Neighbors.java +++ b/core/src/main/java/apoc/neighbors/Neighbors.java @@ -4,9 +4,9 @@ import apoc.result.LongResult; import apoc.result.NodeListResult; import apoc.result.NodeResult; +import apoc.util.collection.Pair; import org.neo4j.graphdb.*; import org.neo4j.internal.helpers.collection.Iterables; -import org.neo4j.internal.helpers.collection.Pair; import org.neo4j.procedure.Context; import org.neo4j.procedure.Description; import org.neo4j.procedure.Name; diff --git a/core/src/main/java/apoc/nodes/Nodes.java b/core/src/main/java/apoc/nodes/Nodes.java index e831dcecb..f842615aa 100644 --- a/core/src/main/java/apoc/nodes/Nodes.java +++ b/core/src/main/java/apoc/nodes/Nodes.java @@ -11,6 +11,7 @@ import apoc.result.VirtualNode; import apoc.result.VirtualPath; import apoc.result.VirtualPathResult; +import apoc.util.collection.Pair; import apoc.util.Util; import org.neo4j.graphalgo.BasicEvaluationContext; import org.neo4j.graphalgo.GraphAlgoFactory; @@ -27,11 +28,9 @@ import org.neo4j.graphdb.RelationshipType; import org.neo4j.graphdb.Transaction; import org.neo4j.internal.helpers.collection.Iterables; -import org.neo4j.internal.helpers.collection.Pair; import org.neo4j.internal.kernel.api.CursorFactory; import org.neo4j.internal.kernel.api.NodeCursor; import org.neo4j.internal.kernel.api.Read; -//import org.neo4j.internal.kernel.api.RelationshipGroupCursor; import org.neo4j.internal.kernel.api.RelationshipTraversalCursor; import org.neo4j.internal.kernel.api.TokenRead; import org.neo4j.kernel.api.KernelTransaction; diff --git a/core/src/main/java/apoc/path/RelationshipSequenceExpander.java b/core/src/main/java/apoc/path/RelationshipSequenceExpander.java index ed36d1740..d98da29e4 100644 --- a/core/src/main/java/apoc/path/RelationshipSequenceExpander.java +++ b/core/src/main/java/apoc/path/RelationshipSequenceExpander.java @@ -1,5 +1,6 @@ package apoc.path; +import apoc.util.collection.Pair; import java.util.ArrayList; import java.util.List; @@ -15,7 +16,6 @@ import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.internal.helpers.collection.NestingResourceIterator; -import org.neo4j.internal.helpers.collection.Pair; import org.neo4j.internal.helpers.collection.ResourceClosingIterator; /** diff --git a/core/src/main/java/apoc/periodic/Periodic.java b/core/src/main/java/apoc/periodic/Periodic.java index 3867ac572..1f458f438 100644 --- a/core/src/main/java/apoc/periodic/Periodic.java +++ b/core/src/main/java/apoc/periodic/Periodic.java @@ -1,6 +1,7 @@ package apoc.periodic; import apoc.Pools; +import apoc.util.collection.Pair; import apoc.util.Util; import apoc.periodic.PeriodicUtils.JobInfo; import org.neo4j.graphdb.GraphDatabaseService; @@ -11,7 +12,6 @@ import org.neo4j.graphdb.schema.Schema; import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.internal.helpers.collection.Iterators; -import org.neo4j.internal.helpers.collection.Pair; import org.neo4j.logging.Log; import org.neo4j.procedure.*; diff --git a/core/src/main/java/apoc/refactor/util/RefactorUtil.java b/core/src/main/java/apoc/refactor/util/RefactorUtil.java index c3493f28f..10dc91bee 100644 --- a/core/src/main/java/apoc/refactor/util/RefactorUtil.java +++ b/core/src/main/java/apoc/refactor/util/RefactorUtil.java @@ -1,7 +1,7 @@ package apoc.refactor.util; +import apoc.util.collection.Pair; import org.neo4j.graphdb.*; -import org.neo4j.internal.helpers.collection.Pair; import java.util.List; import java.util.Map; diff --git a/core/src/main/java/apoc/stats/DegreeDistribution.java b/core/src/main/java/apoc/stats/DegreeDistribution.java index a80c7c55f..39f557fa2 100644 --- a/core/src/main/java/apoc/stats/DegreeDistribution.java +++ b/core/src/main/java/apoc/stats/DegreeDistribution.java @@ -2,11 +2,11 @@ import apoc.Pools; import apoc.path.RelationshipTypeAndDirections; +import apoc.util.collection.Pair; import apoc.util.kernel.MultiThreadedGlobalGraphOperations; import org.HdrHistogram.AtomicHistogram; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.RelationshipType; -import org.neo4j.internal.helpers.collection.Pair; import org.neo4j.internal.kernel.api.CursorFactory; import org.neo4j.internal.kernel.api.NodeCursor; import org.neo4j.internal.kernel.api.Read; diff --git a/core/src/main/java/apoc/text/Strings.java b/core/src/main/java/apoc/text/Strings.java index ed28b03cf..26815ce4b 100644 --- a/core/src/main/java/apoc/text/Strings.java +++ b/core/src/main/java/apoc/text/Strings.java @@ -1,5 +1,6 @@ package apoc.text; +import apoc.util.collection.Pair; import apoc.util.Util; import org.apache.commons.lang3.StringUtils; import org.apache.commons.text.similarity.HammingDistance; @@ -8,7 +9,6 @@ import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Pair; import org.neo4j.procedure.Context; import org.neo4j.procedure.Description; import org.neo4j.procedure.Name; diff --git a/core/src/test/java/apoc/periodic/PeriodicUtilsTest.java b/core/src/test/java/apoc/periodic/PeriodicUtilsTest.java index f01ce10fc..5550acf9a 100644 --- a/core/src/test/java/apoc/periodic/PeriodicUtilsTest.java +++ b/core/src/test/java/apoc/periodic/PeriodicUtilsTest.java @@ -1,7 +1,7 @@ package apoc.periodic; +import apoc.util.collection.Pair; import org.junit.Test; -import org.neo4j.internal.helpers.collection.Pair; import java.util.List; diff --git a/core/src/test/java/apoc/util/UtilTest.java b/core/src/test/java/apoc/util/UtilTest.java index a0ae0c420..16e6d0901 100644 --- a/core/src/test/java/apoc/util/UtilTest.java +++ b/core/src/test/java/apoc/util/UtilTest.java @@ -1,5 +1,6 @@ package apoc.util; +import apoc.util.collection.Pair; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; @@ -8,7 +9,6 @@ import org.neo4j.graphdb.QueryExecutionException; import org.neo4j.graphdb.ResultTransformer; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Pair; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/test-utils/build.gradle b/test-utils/build.gradle index 2f8b3ba26..c8fb7775d 100644 --- a/test-utils/build.gradle +++ b/test-utils/build.gradle @@ -36,6 +36,7 @@ dependencies { api group: 'org.apache.arrow', name: 'arrow-vector', version: '7.0.0' api group: 'org.apache.arrow', name: 'arrow-memory-netty', version: '7.0.0' + implementation project(":common") implementation group: 'org.neo4j', name: 'neo4j-common', version: neo4jVersionEffective, classifier: "tests" implementation group: 'org.neo4j', name: 'neo4j-kernel', version: neo4jVersionEffective, classifier: "tests" implementation group: 'org.neo4j', name: 'neo4j-io', version: neo4jVersionEffective, classifier: "tests" diff --git a/test-utils/src/main/java/apoc/util/SensitivePathGenerator.java b/test-utils/src/main/java/apoc/util/SensitivePathGenerator.java index ea3058e7e..d3aa4196e 100644 --- a/test-utils/src/main/java/apoc/util/SensitivePathGenerator.java +++ b/test-utils/src/main/java/apoc/util/SensitivePathGenerator.java @@ -1,6 +1,6 @@ package apoc.util; -import org.neo4j.internal.helpers.collection.Pair; +import apoc.util.collection.Pair; import org.neo4j.kernel.internal.GraphDatabaseAPI; import java.nio.file.Path; From ff193a40d86b061e16f1e9daa777291470bd7651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louise=20S=C3=B6derstr=C3=B6m?= Date: Thu, 15 Sep 2022 14:44:44 +0200 Subject: [PATCH 2/9] Copy over relevant parts of Iterators and Iterables To reduce dependencies of internal Neo4j APIs --- .../main/java/apoc/convert/ConvertUtils.java | 3 +- .../formatter/AbstractCypherFormatter.java | 2 +- .../formatter/CypherFormatterUtils.java | 2 +- .../apoc/export/util/MetaInformation.java | 2 +- .../export/util/NodesAndRelsSubGraph.java | 2 +- .../src/main/java/apoc/graph/GraphsUtils.java | 2 +- .../main/java/apoc/result/VirtualNode.java | 2 +- .../main/java/apoc/result/WrappedNode.java | 2 +- .../java/apoc/trigger/TriggerHandler.java | 2 +- .../java/apoc/trigger/TriggerMetadata.java | 2 +- common/src/main/java/apoc/util/Util.java | 2 +- .../collection/AbstractResourceIterable.java | 183 +++++++++++++ .../java/apoc/util/collection/Iterables.java | 243 ++++++++++++++++++ .../java/apoc/util/collection/Iterators.java | 225 ++++++++++++++++ .../apoc/util/collection/MapIterable.java | 48 ++++ .../util/collection/PrefetchingIterator.java | 66 +++++ .../PrefetchingResourceIterator.java | 6 + .../ResourceIteratorCloseFailedException.java | 17 ++ .../collection/WrappingResourceIterator.java | 27 ++ .../cypher/export/CypherResultSubGraph.java | 8 +- .../org/neo4j/cypher/export/SubGraph.java | 2 +- .../RelationshipTypeAndDirectionsTest.java | 2 +- .../java/apoc/result/VirtualNodeTest.java | 2 +- core/src/main/java/apoc/create/Create.java | 2 +- .../java/apoc/cypher/CypherInitializer.java | 2 +- .../export/arrow/ExportGraphFileStrategy.java | 2 +- .../export/arrow/ExportGraphStrategy.java | 2 +- .../arrow/ExportGraphStreamStrategy.java | 2 +- .../export/arrow/ExportResultStrategy.java | 3 +- .../java/apoc/export/cypher/ExportCypher.java | 2 +- .../MultiStatementCypherSubGraphExporter.java | 2 +- .../apoc/export/graphml/ExportGraphML.java | 2 +- core/src/main/java/apoc/graph/Graphs.java | 2 +- .../src/main/java/apoc/index/SchemaIndex.java | 4 +- core/src/main/java/apoc/meta/Meta.java | 2 +- .../main/java/apoc/neighbors/Neighbors.java | 5 +- core/src/main/java/apoc/nodes/Grouping.java | 2 +- core/src/main/java/apoc/nodes/Nodes.java | 2 +- .../src/main/java/apoc/path/PathExplorer.java | 2 +- core/src/main/java/apoc/path/Paths.java | 2 +- .../path/RelationshipSequenceExpander.java | 4 +- .../src/main/java/apoc/periodic/Periodic.java | 4 +- .../java/apoc/refactor/GraphRefactoring.java | 2 +- core/src/main/java/apoc/schema/Schemas.java | 2 +- .../java/apoc/agg/GraphAggregationTest.java | 2 +- .../test/java/apoc/algo/PathFindingTest.java | 2 +- core/src/test/java/apoc/coll/CollTest.java | 2 +- .../src/test/java/apoc/create/CreateTest.java | 2 +- .../apoc/cypher/CypherInitializerTest.java | 2 +- .../src/test/java/apoc/cypher/CypherTest.java | 4 +- core/src/test/java/apoc/date/DateTest.java | 2 +- core/src/test/java/apoc/diff/DiffTest.java | 2 +- .../export/csv/ExportCsvNeo4jAdminTest.java | 2 +- .../java/apoc/export/csv/ExportCsvTest.java | 2 +- .../cypher/ExportCypherMultiRelTest.java | 2 +- .../export/graphml/ExportGraphMLTest.java | 2 +- .../java/apoc/export/json/ImportJsonTest.java | 2 +- core/src/test/java/apoc/graph/GraphsTest.java | 2 +- .../src/test/java/apoc/load/LoadJsonTest.java | 2 +- core/src/test/java/apoc/load/XmlTest.java | 4 +- core/src/test/java/apoc/lock/LockTest.java | 2 +- .../java/apoc/log/Neo4jLogStreamTest.java | 2 +- core/src/test/java/apoc/map/MapsTest.java | 2 +- core/src/test/java/apoc/merge/MergeTest.java | 2 +- core/src/test/java/apoc/meta/MetaTest.java | 4 +- .../test/java/apoc/nodes/GroupingTest.java | 2 +- core/src/test/java/apoc/nodes/NodesTest.java | 6 +- .../test/java/apoc/path/ExpandPathTest.java | 2 +- .../test/java/apoc/path/NodeFilterTest.java | 2 +- .../test/java/apoc/path/RelSequenceTest.java | 2 +- .../test/java/apoc/periodic/PeriodicTest.java | 2 +- .../apoc/refactor/GraphRefactoringTest.java | 2 +- .../test/java/apoc/schema/SchemasTest.java | 2 +- core/src/test/java/apoc/text/StringsTest.java | 2 +- .../java/apoc/trigger/TriggerRestartTest.java | 2 +- .../src/main/java/apoc/algo/AlgoUtil.java | 2 +- .../java/apoc/periodic/PeriodicTestUtils.java | 2 +- .../src/main/java/apoc/util/TestUtil.java | 4 +- 78 files changed, 898 insertions(+), 86 deletions(-) create mode 100644 common/src/main/java/apoc/util/collection/AbstractResourceIterable.java create mode 100644 common/src/main/java/apoc/util/collection/Iterables.java create mode 100644 common/src/main/java/apoc/util/collection/Iterators.java create mode 100644 common/src/main/java/apoc/util/collection/MapIterable.java create mode 100644 common/src/main/java/apoc/util/collection/PrefetchingIterator.java create mode 100644 common/src/main/java/apoc/util/collection/PrefetchingResourceIterator.java create mode 100644 common/src/main/java/apoc/util/collection/ResourceIteratorCloseFailedException.java create mode 100644 common/src/main/java/apoc/util/collection/WrappingResourceIterator.java diff --git a/common/src/main/java/apoc/convert/ConvertUtils.java b/common/src/main/java/apoc/convert/ConvertUtils.java index e99494576..bbf91e2f2 100644 --- a/common/src/main/java/apoc/convert/ConvertUtils.java +++ b/common/src/main/java/apoc/convert/ConvertUtils.java @@ -1,7 +1,6 @@ package apoc.convert; -import org.neo4j.internal.helpers.collection.Iterators; - +import apoc.util.collection.Iterators; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collection; diff --git a/common/src/main/java/apoc/export/cypher/formatter/AbstractCypherFormatter.java b/common/src/main/java/apoc/export/cypher/formatter/AbstractCypherFormatter.java index bc066d0b4..bd902aaf4 100644 --- a/common/src/main/java/apoc/export/cypher/formatter/AbstractCypherFormatter.java +++ b/common/src/main/java/apoc/export/cypher/formatter/AbstractCypherFormatter.java @@ -4,6 +4,7 @@ import apoc.export.util.ExportFormat; import apoc.export.util.Reporter; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.apache.commons.lang3.StringUtils; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.GraphDatabaseService; @@ -12,7 +13,6 @@ import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.RelationshipType; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Iterables; import java.io.PrintWriter; import java.util.*; diff --git a/common/src/main/java/apoc/export/cypher/formatter/CypherFormatterUtils.java b/common/src/main/java/apoc/export/cypher/formatter/CypherFormatterUtils.java index d0b34b63f..bfe665605 100644 --- a/common/src/main/java/apoc/export/cypher/formatter/CypherFormatterUtils.java +++ b/common/src/main/java/apoc/export/cypher/formatter/CypherFormatterUtils.java @@ -2,10 +2,10 @@ import apoc.export.util.FormatUtils; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Relationship; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.values.storable.DurationValue; import org.neo4j.values.storable.Value; import org.neo4j.values.storable.Values; diff --git a/common/src/main/java/apoc/export/util/MetaInformation.java b/common/src/main/java/apoc/export/util/MetaInformation.java index 6d2d85cd1..789e6e8b5 100644 --- a/common/src/main/java/apoc/export/util/MetaInformation.java +++ b/common/src/main/java/apoc/export/util/MetaInformation.java @@ -21,8 +21,8 @@ import static apoc.gephi.GephiFormatUtils.getCaption; import static apoc.meta.tablesforlabels.PropertyTracker.typeMappings; +import static apoc.util.collection.Iterables.stream; import static java.util.Arrays.asList; -import static org.neo4j.internal.helpers.collection.Iterables.stream; /** * @author mh diff --git a/common/src/main/java/apoc/export/util/NodesAndRelsSubGraph.java b/common/src/main/java/apoc/export/util/NodesAndRelsSubGraph.java index ce5457165..40a9dc328 100644 --- a/common/src/main/java/apoc/export/util/NodesAndRelsSubGraph.java +++ b/common/src/main/java/apoc/export/util/NodesAndRelsSubGraph.java @@ -1,5 +1,6 @@ package apoc.export.util; +import apoc.util.collection.Iterables; import org.neo4j.cypher.export.SubGraph; import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Node; @@ -9,7 +10,6 @@ import org.neo4j.graphdb.schema.ConstraintDefinition; import org.neo4j.graphdb.schema.IndexDefinition; import org.neo4j.graphdb.schema.Schema; -import org.neo4j.internal.helpers.collection.Iterables; import java.util.ArrayList; import java.util.Collection; diff --git a/common/src/main/java/apoc/graph/GraphsUtils.java b/common/src/main/java/apoc/graph/GraphsUtils.java index b5d4138e0..3ad0ff1fd 100644 --- a/common/src/main/java/apoc/graph/GraphsUtils.java +++ b/common/src/main/java/apoc/graph/GraphsUtils.java @@ -1,12 +1,12 @@ package apoc.graph; +import apoc.util.collection.Iterables; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Path; import org.neo4j.graphdb.Relationship; -import org.neo4j.internal.helpers.collection.Iterables; public class GraphsUtils { public static boolean extract(Object data, Set nodes, Set rels) { diff --git a/common/src/main/java/apoc/result/VirtualNode.java b/common/src/main/java/apoc/result/VirtualNode.java index c6926de9d..36c5d6e39 100644 --- a/common/src/main/java/apoc/result/VirtualNode.java +++ b/common/src/main/java/apoc/result/VirtualNode.java @@ -1,9 +1,9 @@ package apoc.result; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.neo4j.graphdb.*; import org.neo4j.internal.helpers.collection.FilteringIterable; -import org.neo4j.internal.helpers.collection.Iterables; import java.util.*; import java.util.concurrent.atomic.AtomicLong; diff --git a/common/src/main/java/apoc/result/WrappedNode.java b/common/src/main/java/apoc/result/WrappedNode.java index 4e1bbab8f..adf221dac 100644 --- a/common/src/main/java/apoc/result/WrappedNode.java +++ b/common/src/main/java/apoc/result/WrappedNode.java @@ -1,8 +1,8 @@ package apoc.result; +import apoc.util.collection.Iterables; import org.neo4j.graphdb.*; import org.neo4j.internal.helpers.collection.FilteringIterable; -import org.neo4j.internal.helpers.collection.Iterables; import java.util.*; import java.util.concurrent.atomic.AtomicLong; diff --git a/common/src/main/java/apoc/trigger/TriggerHandler.java b/common/src/main/java/apoc/trigger/TriggerHandler.java index 84f2cd65b..a0c7eebf8 100644 --- a/common/src/main/java/apoc/trigger/TriggerHandler.java +++ b/common/src/main/java/apoc/trigger/TriggerHandler.java @@ -4,6 +4,7 @@ import apoc.Pools; import apoc.SystemLabels; import apoc.SystemPropertyKeys; +import apoc.util.collection.Iterators; import apoc.util.collection.Pair; import apoc.util.Util; import org.neo4j.dbms.api.DatabaseManagementService; @@ -14,7 +15,6 @@ import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.event.TransactionData; import org.neo4j.graphdb.event.TransactionEventListener; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.internal.helpers.collection.MapUtil; import org.neo4j.internal.kernel.api.exceptions.ProcedureException; import org.neo4j.kernel.api.procedure.Context; diff --git a/common/src/main/java/apoc/trigger/TriggerMetadata.java b/common/src/main/java/apoc/trigger/TriggerMetadata.java index 74ccf5575..ca428278b 100644 --- a/common/src/main/java/apoc/trigger/TriggerMetadata.java +++ b/common/src/main/java/apoc/trigger/TriggerMetadata.java @@ -4,6 +4,7 @@ import apoc.result.VirtualNode; import apoc.result.VirtualRelationship; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.neo4j.graphdb.Entity; import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Node; @@ -12,7 +13,6 @@ import org.neo4j.graphdb.event.LabelEntry; import org.neo4j.graphdb.event.PropertyEntry; import org.neo4j.graphdb.event.TransactionData; -import org.neo4j.internal.helpers.collection.Iterables; import java.util.ArrayList; import java.util.Collections; diff --git a/common/src/main/java/apoc/util/Util.java b/common/src/main/java/apoc/util/Util.java index 54046ad68..0bb49f265 100644 --- a/common/src/main/java/apoc/util/Util.java +++ b/common/src/main/java/apoc/util/Util.java @@ -7,6 +7,7 @@ import apoc.export.util.ExportConfig; import apoc.result.VirtualNode; import apoc.result.VirtualRelationship; +import apoc.util.collection.Iterators; import apoc.util.collection.Pair; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveInputStream; @@ -89,7 +90,6 @@ import org.neo4j.graphdb.ResourceIterator; import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.TransactionTerminatedException; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.internal.kernel.api.procs.ProcedureCallContext; import org.neo4j.internal.kernel.api.security.SecurityContext; import org.neo4j.kernel.internal.GraphDatabaseAPI; diff --git a/common/src/main/java/apoc/util/collection/AbstractResourceIterable.java b/common/src/main/java/apoc/util/collection/AbstractResourceIterable.java new file mode 100644 index 000000000..ffc5d198c --- /dev/null +++ b/common/src/main/java/apoc/util/collection/AbstractResourceIterable.java @@ -0,0 +1,183 @@ +package apoc.util.collection; + +import java.util.Arrays; +import java.util.BitSet; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Function; +import org.neo4j.graphdb.ResourceIterable; +import org.neo4j.graphdb.ResourceIterator; + +public abstract class AbstractResourceIterable implements ResourceIterable +{ + // start with 2 as most cases will only generate a single iterator but gives a little leeway to save on expansions + private TrackingResourceIterator[] trackedIterators = new TrackingResourceIterator[2]; + + private BitSet trackedIteratorsInUse = new BitSet(); + + private boolean closed; + + protected abstract ResourceIterator newIterator(); + + @Override + public final ResourceIterator iterator() + { + if ( closed ) + { + throw new ResourceIteratorCloseFailedException( ResourceIterable.class.getSimpleName() + " has already been closed" ); + } + + return new TrackingResourceIterator<>( Objects.requireNonNull( newIterator() ), this::register, this::unregister ); + } + + @Override + public final void close() + { + if ( !closed ) + { + try + { + internalClose(); + } + finally + { + closed = true; + onClosed(); + } + } + } + + /** + * Callback method that allows subclasses to perform their own specific closing logic + */ + protected void onClosed() + { + } + + private void register( TrackingResourceIterator iterator ) + { + if ( trackedIteratorsInUse.cardinality() == trackedIterators.length ) + { + trackedIterators = Arrays.copyOf( trackedIterators, trackedIterators.length << 1 ); + } + + final var freeIndex = trackedIteratorsInUse.nextClearBit( 0 ); + trackedIterators[freeIndex] = iterator; + trackedIteratorsInUse.set( freeIndex ); + } + + private void unregister( TrackingResourceIterator iterator ) + { + final var lastSetBit = trackedIteratorsInUse.previousSetBit( trackedIterators.length ); + for ( int i = 0; i <= lastSetBit; i++ ) + { + if ( trackedIterators[i] == iterator ) + { + trackedIterators[i] = null; + trackedIteratorsInUse.clear( i ); + break; + } + } + } + + private void internalClose() + { + ResourceIteratorCloseFailedException closeThrowable = null; + final var lastSetBit = trackedIteratorsInUse.previousSetBit( trackedIterators.length ); + for ( int i = 0; i <= lastSetBit; i++ ) + { + if ( trackedIterators[i] == null ) + { + continue; + } + + try + { + trackedIterators[i].internalClose(); + } + catch ( Exception e ) + { + if ( closeThrowable == null ) + { + closeThrowable = new ResourceIteratorCloseFailedException( "Exception closing a resource iterator.", e ); + } + else + { + closeThrowable.addSuppressed( e ); + } + } + } + + trackedIterators = null; + trackedIteratorsInUse = null; + + if ( closeThrowable != null ) + { + throw closeThrowable; + } + } + + private static final class TrackingResourceIterator implements ResourceIterator + { + private final ResourceIterator delegate; + private final Consumer> registerCallback; + private final Consumer> unregisterCallback; + + private boolean closed; + + private TrackingResourceIterator( ResourceIterator delegate, Consumer> registerCallback, + Consumer> unregisterCallback ) + { + this.delegate = delegate; + this.registerCallback = registerCallback; + this.unregisterCallback = unregisterCallback; + + registerCallback.accept( this ); + } + + @Override + public boolean hasNext() + { + boolean hasNext = delegate.hasNext(); + if ( !hasNext ) + { + close(); + } + return hasNext; + } + + @Override + public T next() + { + return delegate.next(); + } + + @Override + public ResourceIterator map( Function map ) + { + return new TrackingResourceIterator<>( ResourceIterator.super.map( map ), registerCallback, unregisterCallback ); + } + + @Override + public void close() + { + if ( !closed ) + { + internalClose(); + unregisterCallback.accept( this ); + } + } + + private void internalClose() + { + try + { + delegate.close(); + } + finally + { + closed = true; + } + } + } +} diff --git a/common/src/main/java/apoc/util/collection/Iterables.java b/common/src/main/java/apoc/util/collection/Iterables.java new file mode 100644 index 000000000..2b5f1b729 --- /dev/null +++ b/common/src/main/java/apoc/util/collection/Iterables.java @@ -0,0 +1,243 @@ +package apoc.util.collection; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Stream; +import org.neo4j.graphdb.Resource; +import org.neo4j.graphdb.ResourceIterable; +import org.neo4j.graphdb.ResourceIterator; + +/** + * Utility methods for processing iterables. Where possible, If the iterable implements + * {@link Resource}, it will be {@link Resource#close() closed} when the processing + * has been completed. + */ +public final class Iterables { + + /** + * Collect all the elements available in {@code iterable} and add them to the + * provided {@code collection}. + *

+ * If the {@code iterable} implements {@link Resource} it will be + * {@link Resource#close() closed} in a {@code finally} block after all + * the items have been added. + * + * @param collection the collection to add items to. + * @param iterable the iterable from which items will be collected + * @param the type of elements in {@code iterable}. + * @param the type of the collection to add the items to. + * @return the {@code collection} that has been updated. + */ + public static > C addAll(C collection, Iterable iterable) { + try { + Iterator iterator = iterable.iterator(); + try { + while (iterator.hasNext()) { + collection.add(iterator.next()); + } + } finally { + Iterators.tryCloseResource(iterator); + } + } finally { + tryCloseResource(iterable); + } + + return collection; + } + + public static Iterable map(Function function, Iterable from) { + return new MapIterable<>(from, function); + } + + @SafeVarargs + public static Iterable iterable(C... items) { + return Arrays.asList(items); + } + + @SuppressWarnings("unchecked") + public static T[] asArray(Class componentType, Iterable iterable) { + if (iterable == null) { + return null; + } + + List list = asList(iterable); + return list.toArray((T[]) Array.newInstance(componentType, list.size())); + } + + public static ResourceIterable asResourceIterable(final Iterable iterable) { + if (iterable instanceof ResourceIterable) { + return (ResourceIterable) iterable; + } + return new AbstractResourceIterable<>() { + @Override + protected ResourceIterator newIterator() { + return Iterators.asResourceIterator(iterable.iterator()); + } + + @Override + protected void onClosed() { + tryCloseResource(iterable); + } + }; + } + + /** + * Returns the given iterable's first element or {@code null} if no + * element found. + *

+ * If the {@code iterable} implements {@link Resource}, then it will be closed in a {@code finally} block + * after the first item has been retrieved, or failed to be retrieved. + *

+ * If the {@link Iterable#iterator() iterator} created by the {@code iterable} implements {@link Resource} + * it will be {@link Resource#close() closed} in a {@code finally} block after the single item + * has been retrieved, or failed to be retrieved. + * + * @param the type of elements in {@code iterable}. + * @param iterable the {@link Iterable} to get elements from. + * @return the first element in the {@code iterable}, or {@code null} if no + * element found. + */ + public static T firstOrNull(Iterable iterable) { + try { + return Iterators.firstOrNull(iterable.iterator()); + } finally { + tryCloseResource(iterable); + } + } + + /** + * Returns the given iterable's first element. If no element is found a + * {@link NoSuchElementException} is thrown. + *

+ * If the {@code iterable} implements {@link Resource}, then it will be closed in a {@code finally} block + * after the first item has been retrieved, or failed to be retrieved. + * + * @param the type of elements in {@code iterable}. + * @param iterable the {@link Iterable} to get elements from. + * @return the first element in the {@code iterable}. + * @throws NoSuchElementException if no element found. + */ + public static T first(Iterable iterable) { + try { + return Iterators.first(iterable.iterator()); + } finally { + tryCloseResource(iterable); + } + } + + /** + * Returns the given iterable's single element. If there are no elements + * or more than one element in the iterable a {@link NoSuchElementException} + * will be thrown. + *

+ * If the {@code iterable} implements {@link Resource}, then it will be closed in a {@code finally} block + * after the single item has been retrieved, or failed to be retrieved. + *

+ * If the {@link Iterable#iterator() iterator} created by the {@code iterable} implements {@link Resource} + * it will be {@link Resource#close() closed} in a {@code finally} block after the single item + * has been retrieved, or failed to be retrieved. + * + * @param the type of elements in {@code iterable}. + * @param iterable the {@link Iterable} to get elements from. + * @return the single element in the {@code iterable}. + * @throws NoSuchElementException if there isn't exactly one element. + */ + public static T single(Iterable iterable) { + try { + return Iterators.single(iterable.iterator()); + } finally { + tryCloseResource(iterable); + } + } + + /** + * Counts the number of items in the {@code iterable} by looping through it. + *

+ * If the {@code iterable} implements {@link Resource}, then it will be closed in a {@code finally} block + * after all its items have been counted. + *

+ * If the {@link Iterable#iterator() iterator} created by the {@code iterable} implements {@link Resource} + * it will be {@link Resource#close() closed} in a {@code finally} block after the items have been counted. + * + * @param the type of items in the iterator. + * @param iterable the {@link Iterable} to count items in. + * @return the number of items found in {@code iterable}. + */ + public static long count(Iterable iterable) { + try { + return Iterators.count(iterable.iterator()); + } finally { + tryCloseResource(iterable); + } + } + + /** + * Creates a list from an iterable. + *

+ * If the {@code iterable} implements {@link Resource}, then it will be closed in a {@code finally} block + * after all its items have been added. + *

+ * If the {@link Iterable#iterator() iterator} created by the {@code iterable} implements {@link Resource} + * it will be {@link Resource#close() closed} in a {@code finally} block after all the items have been added. + * + * @param iterable The iterable to create the list from. + * @param The generic type of both the iterable and the list. + * @return a list containing all items from the iterable. + */ + public static List asList(Iterable iterable) { + return addAll(new ArrayList<>(), iterable); + } + + /** + * Creates a {@link Set} from an {@link Iterable}. + *

+ * If the {@code iterable} implements {@link Resource}, then it will be closed in a {@code finally} block + * after all its items have been added. + *

+ * If the {@link Iterable#iterator() iterator} created by the {@code iterable} implements {@link Resource} + * it will be {@link Resource#close() closed} in a {@code finally} block after all the items have been added. + * + * @param iterable The items to create the set from. + * @param The generic type of items. + * @return a set containing all items from the {@link Iterable}. + */ + public static Set asSet(Iterable iterable) { + return addAll(new HashSet<>(), iterable); + } + + /** + * Create a stream from the given iterable. + *

+ * Note: returned stream needs to be closed via {@link Stream#close()} if the given iterable implements + * {@link Resource}. + * + * @param iterable the iterable to convert to stream + * @param the type of elements in the given iterable + * @return stream over the iterable elements + * @throws NullPointerException when the given iterable is {@code null} + */ + public static Stream stream(Iterable iterable) { + Objects.requireNonNull(iterable); + return Iterators.stream(iterable.iterator()).onClose(() -> tryCloseResource(iterable)); + } + + /** + * Close the provided {@code iterable} if it implements {@link Resource}. + * + * @param iterable the iterable to check for closing + */ + private static void tryCloseResource(Iterable iterable) { + if (iterable instanceof Resource closeable) { + closeable.close(); + } + } +} diff --git a/common/src/main/java/apoc/util/collection/Iterators.java b/common/src/main/java/apoc/util/collection/Iterators.java new file mode 100644 index 000000000..af5848619 --- /dev/null +++ b/common/src/main/java/apoc/util/collection/Iterators.java @@ -0,0 +1,225 @@ +package apoc.util.collection; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.Set; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; +import org.neo4j.graphdb.Resource; +import org.neo4j.graphdb.ResourceIterator; + +/** + * Contains common functionality regarding {@link Iterator}s and + * {@link Iterable}s. + */ +public final class Iterators { + + /** + * Returns the given iterator's first element or {@code null} if no + * element found. + * + * @param the type of elements in {@code iterator}. + * @param iterator the {@link Iterator} to get elements from. + * @return the first element in the {@code iterator}, or {@code null} if no + * element found. + */ + public static T firstOrNull(Iterator iterator) { + try { + return iterator.hasNext() ? iterator.next() : null; + } finally { + tryCloseResource(iterator); + } + } + + /** + * Returns the given iterator's first element. If no element is found a + * {@link NoSuchElementException} is thrown. + * + * @param the type of elements in {@code iterator}. + * @param iterator the {@link Iterator} to get elements from. + * @return the first element in the {@code iterator}. + * @throws NoSuchElementException if no element found. + */ + public static T first(Iterator iterator) { + return assertNotNull(iterator, firstOrNull(iterator)); + } + + /** + * Returns the given iterator's single element or {@code null} if no + * element found. If there is more than one element in the iterator a + * {@link NoSuchElementException} will be thrown. + * + * If the {@code iterator} implements {@link Resource} it will be {@link Resource#close() closed} + * in a {@code finally} block after the single item has been retrieved, or failed to be retrieved. + * + * @param the type of elements in {@code iterator}. + * @param iterator the {@link Iterator} to get elements from. + * @return the single element in {@code iterator}, or {@code null} if no + * element found. + * @throws NoSuchElementException if more than one element was found. + */ + public static T singleOrNull(Iterator iterator) { + try { + T result = iterator.hasNext() ? iterator.next() : null; + if (iterator.hasNext()) { + throw new NoSuchElementException("More than one element in " + iterator + ". First element is '" + + result + "' and the second element is '" + iterator.next() + "'"); + } + return result; + } finally { + tryCloseResource(iterator); + } + } + + /** + * Returns the given iterator's single element. If there are no elements + * or more than one element in the iterator a {@link NoSuchElementException} + * will be thrown. + * + * If the {@code iterator} implements {@link Resource} it will be {@link Resource#close() closed} + * in a {@code finally} block after the single item has been retrieved, or failed to be retrieved. + * + * @param the type of elements in {@code iterator}. + * @param iterator the {@link Iterator} to get elements from. + * @return the single element in the {@code iterator}. + * @throws NoSuchElementException if there isn't exactly one element. + */ + public static T single(Iterator iterator) { + return assertNotNull(iterator, singleOrNull(iterator)); + } + + private static T assertNotNull(Iterator iterator, T result) { + if (result == null) { + throw new NoSuchElementException("No element found in " + iterator); + } + return result; + } + + /** + * Adds all the items in {@code iterator} to {@code collection}. + * @param the type of {@link Collection} to add to items to. + * @param the type of items in the collection and iterator. + * @param iterator the {@link Iterator} to grab the items from. + * @param collection the {@link Collection} to add the items to. + * @return the {@code collection} which was passed in, now filled + * with the items from {@code iterator}. + */ + public static , T> C addToCollection(Iterator iterator, C collection) { + try { + while (iterator.hasNext()) { + collection.add(iterator.next()); + } + return collection; + } finally { + tryCloseResource(iterator); + } + } + + /** + * Convenience method for looping over an {@link Iterator}. Converts the + * {@link Iterator} to an {@link Iterable} by wrapping it in an + * {@link Iterable} that returns the {@link Iterator}. It breaks the + * contract of {@link Iterable} in that it returns the supplied iterator + * instance for each call to {@code iterator()} on the returned + * {@link Iterable} instance. This method exists to make it easy to use an + * {@link Iterator} in a for-loop. + * + * @param the type of items in the iterator. + * @param iterator the iterator to expose as an {@link Iterable}. + * @return the supplied iterator posing as an {@link Iterable}. + */ + public static Iterable loop(final Iterator iterator) { + return () -> iterator; + } + + /** + * Counts the number of items in the {@code iterator} by looping + * through it. + * + * If the {@code iterator} implements {@link Resource} it will be {@link Resource#close() closed} + * in a {@code finally} block after the items have been counted. + * + * @param the type of items in the iterator. + * @param iterator the {@link Iterator} to count items in. + * @return the number of items found in {@code iterator}. + */ + public static long count(Iterator iterator) { + try { + long result = 0; + while (iterator.hasNext()) { + iterator.next(); + result++; + } + return result; + } finally { + tryCloseResource(iterator); + } + } + + public static List asList(Iterator iterator) { + return addToCollection(iterator, new ArrayList<>()); + } + + public static Set asSet(Iterator iterator) { + return addToCollection(iterator, new HashSet<>()); + } + + /** + * Creates a {@link Set} from an array of items.an + * + * @param items the items to add to the set. + * @param the type of the items + * @return the {@link Set} containing the items. + */ + @SafeVarargs + public static Set asSet(T... items) { + return new HashSet<>(Arrays.asList(items)); + } + + public static ResourceIterator asResourceIterator(final Iterator iterator) { + if (iterator instanceof ResourceIterator) { + return (ResourceIterator) iterator; + } + return new WrappingResourceIterator<>(iterator); + } + + /** + * Create a stream from the given iterator. + *

+ * Note: returned stream needs to be closed via {@link Stream#close()} if the given iterator implements + * {@link Resource}. + * + * @param iterator the iterator to convert to stream + * @param the type of elements in the given iterator + * @return stream over the iterator elements + * @throws NullPointerException when the given stream is {@code null} + */ + public static Stream stream(Iterator iterator) { + Objects.requireNonNull(iterator); + Spliterator spliterator = Spliterators.spliteratorUnknownSize(iterator, 0); + Stream stream = StreamSupport.stream(spliterator, false); + if (iterator instanceof Resource resource) { + return stream.onClose(resource::close); + } + return stream; + } + + /** + * Close the provided {@code iterator} if it implements {@link Resource}. + * + * @param iterator the iterator to check for closing + */ + public static void tryCloseResource(Iterator iterator) { + if (iterator instanceof Resource closeable) { + closeable.close(); + } + } +} diff --git a/common/src/main/java/apoc/util/collection/MapIterable.java b/common/src/main/java/apoc/util/collection/MapIterable.java new file mode 100644 index 000000000..36ac6ff7e --- /dev/null +++ b/common/src/main/java/apoc/util/collection/MapIterable.java @@ -0,0 +1,48 @@ +package apoc.util.collection; + + +import java.util.Iterator; +import java.util.function.Function; + +class MapIterable implements Iterable { + private final Iterable from; + private final Function function; + + MapIterable(Iterable from, Function function) { + this.from = from; + this.function = function; + } + + @Override + public Iterator iterator() { + return new MapIterator<>(from.iterator(), function); + } + + static class MapIterator implements Iterator { + private final Iterator fromIterator; + private final Function function; + + MapIterator(Iterator fromIterator, Function function) { + this.fromIterator = fromIterator; + this.function = function; + } + + @Override + public boolean hasNext() { + return fromIterator.hasNext(); + } + + @Override + public TO next() { + FROM from = fromIterator.next(); + + return function.apply(from); + } + + @Override + public void remove() { + fromIterator.remove(); + } + } +} + diff --git a/common/src/main/java/apoc/util/collection/PrefetchingIterator.java b/common/src/main/java/apoc/util/collection/PrefetchingIterator.java new file mode 100644 index 000000000..475229a7a --- /dev/null +++ b/common/src/main/java/apoc/util/collection/PrefetchingIterator.java @@ -0,0 +1,66 @@ +package apoc.util.collection; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * Abstract class for how you usually implement iterators when you don't know + * how many objects there are (which is pretty much every time) + * + * Basically the {@link #hasNext()} method will look up the next object and + * cache it. The cached object is then set to {@code null} in {@link #next()}. + * So you only have to implement one method, {@code fetchNextOrNull} which + * returns {@code null} when the iteration has reached the end, and you're done. + */ +public abstract class PrefetchingIterator implements Iterator { + private boolean hasFetchedNext; + private T nextObject; + + /** + * @return {@code true} if there is a next item to be returned from the next + * call to {@link #next()}. + */ + @Override + public boolean hasNext() { + return peek() != null; + } + + /** + * @return the next element that will be returned from {@link #next()} without + * actually advancing the iterator + */ + public T peek() { + if (hasFetchedNext) { + return nextObject; + } + + nextObject = fetchNextOrNull(); + hasFetchedNext = true; + return nextObject; + } + + /** + * Uses {@link #hasNext()} to try to fetch the next item and returns it + * if found, otherwise it throws a {@link NoSuchElementException}. + * + * @return the next item in the iteration, or throws + * {@link NoSuchElementException} if there's no more items to return. + */ + @Override + public T next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + T result = nextObject; + nextObject = null; + hasFetchedNext = false; + return result; + } + + protected abstract T fetchNextOrNull(); + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/java/apoc/util/collection/PrefetchingResourceIterator.java b/common/src/main/java/apoc/util/collection/PrefetchingResourceIterator.java new file mode 100644 index 000000000..e6681ac27 --- /dev/null +++ b/common/src/main/java/apoc/util/collection/PrefetchingResourceIterator.java @@ -0,0 +1,6 @@ +package apoc.util.collection; + +import org.neo4j.graphdb.ResourceIterator; +import org.neo4j.internal.helpers.collection.PrefetchingIterator; + +public abstract class PrefetchingResourceIterator extends PrefetchingIterator implements ResourceIterator {} diff --git a/common/src/main/java/apoc/util/collection/ResourceIteratorCloseFailedException.java b/common/src/main/java/apoc/util/collection/ResourceIteratorCloseFailedException.java new file mode 100644 index 000000000..90072e74a --- /dev/null +++ b/common/src/main/java/apoc/util/collection/ResourceIteratorCloseFailedException.java @@ -0,0 +1,17 @@ +package apoc.util.collection; + +import org.neo4j.graphdb.Resource; + +/** + * This exception is thrown when a checked exception occurs inside {@link Resource#close()}. + * It is a RuntimeException since {@link Resource#close()} is not allowed to throw checked exceptions. + */ +public class ResourceIteratorCloseFailedException extends RuntimeException { + public ResourceIteratorCloseFailedException(String message) { + super(message); + } + + public ResourceIteratorCloseFailedException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/common/src/main/java/apoc/util/collection/WrappingResourceIterator.java b/common/src/main/java/apoc/util/collection/WrappingResourceIterator.java new file mode 100644 index 000000000..e6ca701e1 --- /dev/null +++ b/common/src/main/java/apoc/util/collection/WrappingResourceIterator.java @@ -0,0 +1,27 @@ +package apoc.util.collection; + +import java.util.Iterator; +class WrappingResourceIterator extends PrefetchingResourceIterator +{ + private final Iterator iterator; + + WrappingResourceIterator(Iterator iterator) { + this.iterator = iterator; + } + + @Override + public void close() { + // nothing to release + } + + @Override + public void remove() { + iterator.remove(); + } + + @Override + protected T fetchNextOrNull() { + return iterator.hasNext() ? iterator.next() : null; + } +} + diff --git a/common/src/main/java/org/neo4j/cypher/export/CypherResultSubGraph.java b/common/src/main/java/org/neo4j/cypher/export/CypherResultSubGraph.java index 09ff6e387..bd2d03a8d 100644 --- a/common/src/main/java/org/neo4j/cypher/export/CypherResultSubGraph.java +++ b/common/src/main/java/org/neo4j/cypher/export/CypherResultSubGraph.java @@ -1,17 +1,17 @@ package org.neo4j.cypher.export; +import static apoc.util.collection.Iterators.loop; + +import apoc.util.collection.Iterables; import org.neo4j.graphdb.*; import org.neo4j.graphdb.schema.ConstraintDefinition; import org.neo4j.graphdb.schema.IndexDefinition; import org.neo4j.graphdb.schema.IndexType; -import org.neo4j.internal.helpers.collection.Iterables; import java.util.*; import java.util.stream.Collectors; import java.util.stream.StreamSupport; -import static org.neo4j.internal.helpers.collection.Iterators.loop; - public class CypherResultSubGraph implements SubGraph { @@ -34,7 +34,7 @@ public void add( Node node ) void addNode( long id, Node data ) { nodes.put( id, data ); - labels.addAll( Iterables.asCollection( data.getLabels() ) ); + labels.addAll( Iterables.addAll( new ArrayList<>(), data.getLabels() ) ); } public void add( Relationship rel ) diff --git a/common/src/main/java/org/neo4j/cypher/export/SubGraph.java b/common/src/main/java/org/neo4j/cypher/export/SubGraph.java index 80c931e35..87a9238ab 100644 --- a/common/src/main/java/org/neo4j/cypher/export/SubGraph.java +++ b/common/src/main/java/org/neo4j/cypher/export/SubGraph.java @@ -1,5 +1,6 @@ package org.neo4j.cypher.export; +import apoc.util.collection.Iterables; import org.apache.commons.collections4.CollectionUtils; import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Node; @@ -7,7 +8,6 @@ import org.neo4j.graphdb.RelationshipType; import org.neo4j.graphdb.schema.ConstraintDefinition; import org.neo4j.graphdb.schema.IndexDefinition; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.internal.kernel.api.TokenRead; import java.util.Collection; diff --git a/common/src/test/java/apoc/path/RelationshipTypeAndDirectionsTest.java b/common/src/test/java/apoc/path/RelationshipTypeAndDirectionsTest.java index f7baecd9c..cdc1e571d 100644 --- a/common/src/test/java/apoc/path/RelationshipTypeAndDirectionsTest.java +++ b/common/src/test/java/apoc/path/RelationshipTypeAndDirectionsTest.java @@ -11,10 +11,10 @@ import java.util.Arrays; +import static apoc.util.collection.Iterables.iterable; import static org.junit.Assert.assertEquals; import static org.neo4j.graphdb.Direction.*; import static org.neo4j.graphdb.RelationshipType.withName; -import static org.neo4j.internal.helpers.collection.Iterables.iterable; @RunWith(Parameterized.class) public class RelationshipTypeAndDirectionsTest { diff --git a/common/src/test/java/apoc/result/VirtualNodeTest.java b/common/src/test/java/apoc/result/VirtualNodeTest.java index 5a0792982..f3d2c951a 100644 --- a/common/src/test/java/apoc/result/VirtualNodeTest.java +++ b/common/src/test/java/apoc/result/VirtualNodeTest.java @@ -1,13 +1,13 @@ package apoc.result; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.junit.ClassRule; import org.junit.Test; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.RelationshipType; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/main/java/apoc/create/Create.java b/core/src/main/java/apoc/create/Create.java index 91bd6b61c..c64a0159f 100644 --- a/core/src/main/java/apoc/create/Create.java +++ b/core/src/main/java/apoc/create/Create.java @@ -3,9 +3,9 @@ import apoc.get.Get; import apoc.result.*; import apoc.util.Util; +import apoc.util.collection.Iterables; import apoc.uuid.UuidUtil; import org.neo4j.graphdb.*; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.procedure.*; import java.util.List; diff --git a/core/src/main/java/apoc/cypher/CypherInitializer.java b/core/src/main/java/apoc/cypher/CypherInitializer.java index e388e9c36..1405186e8 100644 --- a/core/src/main/java/apoc/cypher/CypherInitializer.java +++ b/core/src/main/java/apoc/cypher/CypherInitializer.java @@ -2,12 +2,12 @@ import apoc.ApocConfig; import apoc.util.Util; +import apoc.util.collection.Iterators; import apoc.version.Version; import org.apache.commons.configuration2.Configuration; import org.apache.commons.lang3.StringUtils; import org.neo4j.common.DependencyResolver; import org.neo4j.configuration.GraphDatabaseSettings; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.kernel.api.procedure.GlobalProcedures; import org.neo4j.kernel.availability.AvailabilityListener; import org.neo4j.kernel.database.DefaultDatabaseResolver; diff --git a/core/src/main/java/apoc/export/arrow/ExportGraphFileStrategy.java b/core/src/main/java/apoc/export/arrow/ExportGraphFileStrategy.java index 3b0a68f1e..b8ce4967f 100644 --- a/core/src/main/java/apoc/export/arrow/ExportGraphFileStrategy.java +++ b/core/src/main/java/apoc/export/arrow/ExportGraphFileStrategy.java @@ -3,6 +3,7 @@ import apoc.Pools; import apoc.export.util.ProgressReporter; import apoc.result.ProgressInfo; +import apoc.util.collection.Iterables; import org.apache.arrow.memory.BufferAllocator; import org.apache.arrow.memory.RootAllocator; import org.apache.arrow.vector.types.pojo.Schema; @@ -10,7 +11,6 @@ import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Relationship; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.logging.Log; import org.neo4j.procedure.TerminationGuard; diff --git a/core/src/main/java/apoc/export/arrow/ExportGraphStrategy.java b/core/src/main/java/apoc/export/arrow/ExportGraphStrategy.java index f5e5f6bfc..e72f8f577 100644 --- a/core/src/main/java/apoc/export/arrow/ExportGraphStrategy.java +++ b/core/src/main/java/apoc/export/arrow/ExportGraphStrategy.java @@ -1,6 +1,7 @@ package apoc.export.arrow; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.apache.arrow.vector.types.pojo.Field; import org.apache.arrow.vector.types.pojo.Schema; import org.neo4j.cypher.export.SubGraph; @@ -11,7 +12,6 @@ import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.RelationshipType; import org.neo4j.graphdb.ResultTransformer; -import org.neo4j.internal.helpers.collection.Iterables; import java.util.HashMap; import java.util.HashSet; diff --git a/core/src/main/java/apoc/export/arrow/ExportGraphStreamStrategy.java b/core/src/main/java/apoc/export/arrow/ExportGraphStreamStrategy.java index bce979ecd..d7364b18a 100644 --- a/core/src/main/java/apoc/export/arrow/ExportGraphStreamStrategy.java +++ b/core/src/main/java/apoc/export/arrow/ExportGraphStreamStrategy.java @@ -2,6 +2,7 @@ import apoc.Pools; import apoc.result.ByteArrayResult; +import apoc.util.collection.Iterables; import org.apache.arrow.memory.BufferAllocator; import org.apache.arrow.memory.RootAllocator; import org.apache.arrow.vector.VectorSchemaRoot; @@ -11,7 +12,6 @@ import org.apache.arrow.vector.types.pojo.Schema; import org.neo4j.cypher.export.SubGraph; import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.logging.Log; import org.neo4j.procedure.TerminationGuard; diff --git a/core/src/main/java/apoc/export/arrow/ExportResultStrategy.java b/core/src/main/java/apoc/export/arrow/ExportResultStrategy.java index 52eb30fef..36dcd3239 100644 --- a/core/src/main/java/apoc/export/arrow/ExportResultStrategy.java +++ b/core/src/main/java/apoc/export/arrow/ExportResultStrategy.java @@ -2,6 +2,7 @@ import apoc.meta.Types; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.apache.arrow.vector.types.pojo.Field; import org.apache.arrow.vector.types.pojo.Schema; import org.neo4j.cypher.export.SubGraph; @@ -11,8 +12,6 @@ import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.RelationshipType; -import org.neo4j.internal.helpers.collection.Iterables; - import java.util.AbstractMap; import java.util.HashMap; import java.util.List; diff --git a/core/src/main/java/apoc/export/cypher/ExportCypher.java b/core/src/main/java/apoc/export/cypher/ExportCypher.java index 3dee4df84..345d0a7a9 100644 --- a/core/src/main/java/apoc/export/cypher/ExportCypher.java +++ b/core/src/main/java/apoc/export/cypher/ExportCypher.java @@ -9,6 +9,7 @@ import apoc.util.QueueBasedSpliterator; import apoc.util.QueueUtil; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.neo4j.cypher.export.CypherResultSubGraph; import org.neo4j.cypher.export.DatabaseSubGraph; import org.neo4j.cypher.export.SubGraph; @@ -17,7 +18,6 @@ import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.Result; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.procedure.Context; import org.neo4j.procedure.Description; import org.neo4j.procedure.Name; diff --git a/core/src/main/java/apoc/export/cypher/MultiStatementCypherSubGraphExporter.java b/core/src/main/java/apoc/export/cypher/MultiStatementCypherSubGraphExporter.java index c94e5fd55..c557043e8 100644 --- a/core/src/main/java/apoc/export/cypher/MultiStatementCypherSubGraphExporter.java +++ b/core/src/main/java/apoc/export/cypher/MultiStatementCypherSubGraphExporter.java @@ -6,12 +6,12 @@ import apoc.export.util.ExportFormat; import apoc.export.util.Reporter; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.apache.commons.lang3.StringUtils; import org.neo4j.cypher.export.SubGraph; import org.neo4j.graphdb.*; import org.neo4j.graphdb.schema.IndexDefinition; import org.neo4j.graphdb.schema.IndexType; -import org.neo4j.internal.helpers.collection.Iterables; import java.io.PrintWriter; import java.util.*; diff --git a/core/src/main/java/apoc/export/graphml/ExportGraphML.java b/core/src/main/java/apoc/export/graphml/ExportGraphML.java index ce8ab22d7..f8721fc2b 100644 --- a/core/src/main/java/apoc/export/graphml/ExportGraphML.java +++ b/core/src/main/java/apoc/export/graphml/ExportGraphML.java @@ -11,6 +11,7 @@ import apoc.result.ProgressInfo; import apoc.util.FileUtils; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.neo4j.cypher.export.CypherResultSubGraph; import org.neo4j.cypher.export.DatabaseSubGraph; import org.neo4j.cypher.export.SubGraph; @@ -19,7 +20,6 @@ import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.Result; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.procedure.Context; import org.neo4j.procedure.Description; import org.neo4j.procedure.Mode; diff --git a/core/src/main/java/apoc/graph/Graphs.java b/core/src/main/java/apoc/graph/Graphs.java index 3ce986451..cb20e7e0f 100644 --- a/core/src/main/java/apoc/graph/Graphs.java +++ b/core/src/main/java/apoc/graph/Graphs.java @@ -6,12 +6,12 @@ import apoc.result.RowResult; import apoc.result.VirtualGraph; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.apache.commons.lang3.StringUtils; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Path; import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.procedure.*; import java.util.*; diff --git a/core/src/main/java/apoc/index/SchemaIndex.java b/core/src/main/java/apoc/index/SchemaIndex.java index 42eb78a5e..b49ca0a85 100644 --- a/core/src/main/java/apoc/index/SchemaIndex.java +++ b/core/src/main/java/apoc/index/SchemaIndex.java @@ -3,12 +3,12 @@ import apoc.result.ListResult; import apoc.util.QueueBasedSpliterator; import apoc.util.Util; +import apoc.util.collection.Iterables; +import apoc.util.collection.Iterators; import org.neo4j.exceptions.KernelException; import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.schema.IndexDefinition; -import org.neo4j.internal.helpers.collection.Iterables; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.internal.kernel.api.*; import org.neo4j.internal.schema.IndexDescriptor; import org.neo4j.internal.schema.SchemaDescriptors; diff --git a/core/src/main/java/apoc/meta/Meta.java b/core/src/main/java/apoc/meta/Meta.java index f88b6bd4a..9939a658c 100644 --- a/core/src/main/java/apoc/meta/Meta.java +++ b/core/src/main/java/apoc/meta/Meta.java @@ -7,6 +7,7 @@ import apoc.result.VirtualNode; import apoc.result.VirtualRelationship; import apoc.util.MapUtil; +import apoc.util.collection.Iterables; import apoc.util.collection.Pair; import org.apache.commons.collections4.CollectionUtils; import org.neo4j.cypher.export.CypherResultSubGraph; @@ -27,7 +28,6 @@ import org.neo4j.graphdb.schema.ConstraintType; import org.neo4j.graphdb.schema.IndexDefinition; import org.neo4j.graphdb.schema.Schema; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.internal.kernel.api.Read; import org.neo4j.internal.kernel.api.TokenRead; import org.neo4j.kernel.api.KernelTransaction; diff --git a/core/src/main/java/apoc/neighbors/Neighbors.java b/core/src/main/java/apoc/neighbors/Neighbors.java index c0e0c3bcc..e1c2e8da0 100644 --- a/core/src/main/java/apoc/neighbors/Neighbors.java +++ b/core/src/main/java/apoc/neighbors/Neighbors.java @@ -6,7 +6,6 @@ import apoc.result.NodeResult; import apoc.util.collection.Pair; import org.neo4j.graphdb.*; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.procedure.Context; import org.neo4j.procedure.Description; import org.neo4j.procedure.Name; @@ -28,10 +27,10 @@ public class Neighbors { private Iterable getRelationshipsByTypeAndDirection(Node node, Pair typesAndDirection) { // as policy if both elements in the pair are null we return an empty result if (typesAndDirection.first() == null) { - return typesAndDirection.other() == null ? Iterables.empty() : node.getRelationships(typesAndDirection.other()); + return typesAndDirection.other() == null ? Collections.emptyList() : node.getRelationships(typesAndDirection.other()); } if (typesAndDirection.other() == null) { - return typesAndDirection.first() == null ? Iterables.empty() : node.getRelationships(typesAndDirection.first()); + return typesAndDirection.first() == null ? Collections.emptyList() : node.getRelationships(typesAndDirection.first()); } return node.getRelationships(typesAndDirection.other(), typesAndDirection.first()); } diff --git a/core/src/main/java/apoc/nodes/Grouping.java b/core/src/main/java/apoc/nodes/Grouping.java index e74012a34..f38269dd6 100644 --- a/core/src/main/java/apoc/nodes/Grouping.java +++ b/core/src/main/java/apoc/nodes/Grouping.java @@ -5,8 +5,8 @@ import apoc.result.VirtualNode; import apoc.result.VirtualRelationship; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.neo4j.graphdb.*; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.logging.Log; import org.neo4j.procedure.Context; import org.neo4j.procedure.Name; diff --git a/core/src/main/java/apoc/nodes/Nodes.java b/core/src/main/java/apoc/nodes/Nodes.java index f842615aa..f716a6eaa 100644 --- a/core/src/main/java/apoc/nodes/Nodes.java +++ b/core/src/main/java/apoc/nodes/Nodes.java @@ -11,6 +11,7 @@ import apoc.result.VirtualNode; import apoc.result.VirtualPath; import apoc.result.VirtualPathResult; +import apoc.util.collection.Iterables; import apoc.util.collection.Pair; import apoc.util.Util; import org.neo4j.graphalgo.BasicEvaluationContext; @@ -27,7 +28,6 @@ import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.RelationshipType; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.internal.kernel.api.CursorFactory; import org.neo4j.internal.kernel.api.NodeCursor; import org.neo4j.internal.kernel.api.Read; diff --git a/core/src/main/java/apoc/path/PathExplorer.java b/core/src/main/java/apoc/path/PathExplorer.java index ba579ae7d..a1882f86c 100644 --- a/core/src/main/java/apoc/path/PathExplorer.java +++ b/core/src/main/java/apoc/path/PathExplorer.java @@ -5,12 +5,12 @@ import apoc.result.NodeResult; import apoc.result.PathResult; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Path; import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.traversal.*; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.logging.Log; import org.neo4j.procedure.Context; import org.neo4j.procedure.Description; diff --git a/core/src/main/java/apoc/path/Paths.java b/core/src/main/java/apoc/path/Paths.java index 9f3a5f4dd..3482c4167 100644 --- a/core/src/main/java/apoc/path/Paths.java +++ b/core/src/main/java/apoc/path/Paths.java @@ -1,10 +1,10 @@ package apoc.path; +import apoc.util.collection.Iterables; import org.neo4j.graphalgo.impl.util.PathImpl; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Path; import org.neo4j.graphdb.Relationship; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.procedure.Description; import org.neo4j.procedure.Name; import org.neo4j.procedure.UserFunction; diff --git a/core/src/main/java/apoc/path/RelationshipSequenceExpander.java b/core/src/main/java/apoc/path/RelationshipSequenceExpander.java index d98da29e4..fbe12fab7 100644 --- a/core/src/main/java/apoc/path/RelationshipSequenceExpander.java +++ b/core/src/main/java/apoc/path/RelationshipSequenceExpander.java @@ -1,5 +1,7 @@ package apoc.path; +import apoc.util.collection.Iterables; +import apoc.util.collection.Iterators; import apoc.util.collection.Pair; import java.util.ArrayList; import java.util.List; @@ -13,8 +15,6 @@ import org.neo4j.graphdb.ResourceIterable; import org.neo4j.graphdb.ResourceIterator; import org.neo4j.graphdb.traversal.BranchState; -import org.neo4j.internal.helpers.collection.Iterables; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.internal.helpers.collection.NestingResourceIterator; import org.neo4j.internal.helpers.collection.ResourceClosingIterator; diff --git a/core/src/main/java/apoc/periodic/Periodic.java b/core/src/main/java/apoc/periodic/Periodic.java index 1f458f438..3921ab84f 100644 --- a/core/src/main/java/apoc/periodic/Periodic.java +++ b/core/src/main/java/apoc/periodic/Periodic.java @@ -1,6 +1,8 @@ package apoc.periodic; import apoc.Pools; +import apoc.util.collection.Iterables; +import apoc.util.collection.Iterators; import apoc.util.collection.Pair; import apoc.util.Util; import apoc.periodic.PeriodicUtils.JobInfo; @@ -10,8 +12,6 @@ import org.neo4j.graphdb.schema.ConstraintDefinition; import org.neo4j.graphdb.schema.IndexDefinition; import org.neo4j.graphdb.schema.Schema; -import org.neo4j.internal.helpers.collection.Iterables; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.logging.Log; import org.neo4j.procedure.*; diff --git a/core/src/main/java/apoc/refactor/GraphRefactoring.java b/core/src/main/java/apoc/refactor/GraphRefactoring.java index c860af8bd..e962d5393 100644 --- a/core/src/main/java/apoc/refactor/GraphRefactoring.java +++ b/core/src/main/java/apoc/refactor/GraphRefactoring.java @@ -8,10 +8,10 @@ import apoc.result.NodeResult; import apoc.result.RelationshipResult; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.apache.commons.collections4.IterableUtils; import org.neo4j.graphdb.*; import org.neo4j.graphdb.schema.ConstraintType; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.logging.Log; import org.neo4j.procedure.*; diff --git a/core/src/main/java/apoc/schema/Schemas.java b/core/src/main/java/apoc/schema/Schemas.java index ab1f83f93..8a3786d25 100644 --- a/core/src/main/java/apoc/schema/Schemas.java +++ b/core/src/main/java/apoc/schema/Schemas.java @@ -4,6 +4,7 @@ import apoc.result.IndexConstraintNodeInfo; import apoc.result.IndexConstraintRelationshipInfo; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.apache.commons.lang3.StringUtils; import org.neo4j.common.EntityType; import org.neo4j.common.TokenNameLookup; @@ -16,7 +17,6 @@ import org.neo4j.graphdb.schema.IndexDefinition; import org.neo4j.graphdb.schema.IndexType; import org.neo4j.graphdb.schema.Schema; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.internal.kernel.api.InternalIndexState; import org.neo4j.internal.kernel.api.SchemaRead; import org.neo4j.internal.kernel.api.TokenRead; diff --git a/core/src/test/java/apoc/agg/GraphAggregationTest.java b/core/src/test/java/apoc/agg/GraphAggregationTest.java index e7cb743b7..f903648a8 100644 --- a/core/src/test/java/apoc/agg/GraphAggregationTest.java +++ b/core/src/test/java/apoc/agg/GraphAggregationTest.java @@ -16,9 +16,9 @@ import static apoc.util.TestUtil.testCall; import static apoc.util.Util.map; +import static apoc.util.collection.Iterators.asSet; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; -import static org.neo4j.internal.helpers.collection.Iterators.asSet; public class GraphAggregationTest { diff --git a/core/src/test/java/apoc/algo/PathFindingTest.java b/core/src/test/java/apoc/algo/PathFindingTest.java index b558e2776..55cf0bcb8 100644 --- a/core/src/test/java/apoc/algo/PathFindingTest.java +++ b/core/src/test/java/apoc/algo/PathFindingTest.java @@ -1,11 +1,11 @@ package apoc.algo; import apoc.util.TestUtil; +import apoc.util.collection.Iterators; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.neo4j.graphdb.Path; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/coll/CollTest.java b/core/src/test/java/apoc/coll/CollTest.java index 5382ffe80..b496e2446 100644 --- a/core/src/test/java/apoc/coll/CollTest.java +++ b/core/src/test/java/apoc/coll/CollTest.java @@ -14,11 +14,11 @@ import static apoc.util.TestUtil.testCall; import static apoc.util.TestUtil.testResult; import static apoc.util.Util.map; +import static apoc.util.collection.Iterables.asSet; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static junit.framework.TestCase.assertTrue; import static org.junit.Assert.*; -import static org.neo4j.internal.helpers.collection.Iterables.asSet; public class CollTest { diff --git a/core/src/test/java/apoc/create/CreateTest.java b/core/src/test/java/apoc/create/CreateTest.java index b618f4aae..3b49c127a 100644 --- a/core/src/test/java/apoc/create/CreateTest.java +++ b/core/src/test/java/apoc/create/CreateTest.java @@ -2,6 +2,7 @@ import apoc.path.Paths; import apoc.util.TestUtil; +import apoc.util.collection.Iterables; import org.apache.commons.lang3.exception.ExceptionUtils; import org.junit.Before; import org.junit.Rule; @@ -12,7 +13,6 @@ import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.RelationshipType; import org.neo4j.graphdb.ResourceIterator; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/cypher/CypherInitializerTest.java b/core/src/test/java/apoc/cypher/CypherInitializerTest.java index 71f9c7135..0b3a2805c 100644 --- a/core/src/test/java/apoc/cypher/CypherInitializerTest.java +++ b/core/src/test/java/apoc/cypher/CypherInitializerTest.java @@ -6,6 +6,7 @@ import apoc.test.annotations.EnvSetting; import apoc.util.TestUtil; import apoc.util.Utils; +import apoc.util.collection.Iterators; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -14,7 +15,6 @@ import java.util.Collections; import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.kernel.availability.AvailabilityListener; import org.neo4j.kernel.internal.GraphDatabaseAPI; import org.neo4j.test.rule.DbmsRule; diff --git a/core/src/test/java/apoc/cypher/CypherTest.java b/core/src/test/java/apoc/cypher/CypherTest.java index a4657699d..464864f20 100644 --- a/core/src/test/java/apoc/cypher/CypherTest.java +++ b/core/src/test/java/apoc/cypher/CypherTest.java @@ -4,6 +4,8 @@ import apoc.util.TestUtil; import apoc.util.Util; import apoc.util.Utils; +import apoc.util.collection.Iterables; +import apoc.util.collection.Iterators; import org.hamcrest.Matchers; import org.junit.After; import org.junit.BeforeClass; @@ -18,8 +20,6 @@ import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.schema.ConstraintDefinition; import org.neo4j.graphdb.schema.IndexDefinition; -import org.neo4j.internal.helpers.collection.Iterables; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/date/DateTest.java b/core/src/test/java/apoc/date/DateTest.java index 72f7461ae..97324ea5e 100644 --- a/core/src/test/java/apoc/date/DateTest.java +++ b/core/src/test/java/apoc/date/DateTest.java @@ -2,6 +2,7 @@ import apoc.temporal.TemporalProcedures; import apoc.util.TestUtil; +import apoc.util.collection.Iterators; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Rule; @@ -10,7 +11,6 @@ import org.neo4j.graphdb.Node; import org.neo4j.graphdb.QueryExecutionException; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/diff/DiffTest.java b/core/src/test/java/apoc/diff/DiffTest.java index 35b1a503e..c654691cb 100644 --- a/core/src/test/java/apoc/diff/DiffTest.java +++ b/core/src/test/java/apoc/diff/DiffTest.java @@ -2,13 +2,13 @@ import apoc.create.Create; import apoc.util.TestUtil; +import apoc.util.collection.Iterators; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/export/csv/ExportCsvNeo4jAdminTest.java b/core/src/test/java/apoc/export/csv/ExportCsvNeo4jAdminTest.java index d79cba945..1988bed9f 100644 --- a/core/src/test/java/apoc/export/csv/ExportCsvNeo4jAdminTest.java +++ b/core/src/test/java/apoc/export/csv/ExportCsvNeo4jAdminTest.java @@ -5,12 +5,12 @@ import apoc.util.CompressionAlgo; import apoc.util.TestUtil; import apoc.util.Util; +import apoc.util.collection.Iterators; import org.apache.commons.lang.exception.ExceptionUtils; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.neo4j.configuration.GraphDatabaseSettings; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/export/csv/ExportCsvTest.java b/core/src/test/java/apoc/export/csv/ExportCsvTest.java index 195036837..c8c7f8a0d 100644 --- a/core/src/test/java/apoc/export/csv/ExportCsvTest.java +++ b/core/src/test/java/apoc/export/csv/ExportCsvTest.java @@ -7,12 +7,12 @@ import apoc.util.CompressionConfig; import apoc.util.TestUtil; import apoc.util.Util; +import apoc.util.collection.Iterators; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.neo4j.configuration.GraphDatabaseSettings; import org.neo4j.graphdb.Result; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/export/cypher/ExportCypherMultiRelTest.java b/core/src/test/java/apoc/export/cypher/ExportCypherMultiRelTest.java index 3a157c175..bd3e36cd0 100644 --- a/core/src/test/java/apoc/export/cypher/ExportCypherMultiRelTest.java +++ b/core/src/test/java/apoc/export/cypher/ExportCypherMultiRelTest.java @@ -2,13 +2,13 @@ import apoc.cypher.Cypher; import apoc.util.TestUtil; +import apoc.util.collection.Iterators; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.ResourceIterator; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/export/graphml/ExportGraphMLTest.java b/core/src/test/java/apoc/export/graphml/ExportGraphMLTest.java index 6afe2de9b..55f70833b 100644 --- a/core/src/test/java/apoc/export/graphml/ExportGraphMLTest.java +++ b/core/src/test/java/apoc/export/graphml/ExportGraphMLTest.java @@ -6,6 +6,7 @@ import apoc.util.CompressionConfig; import apoc.util.TestUtil; import apoc.util.Util; +import apoc.util.collection.Iterables; import junit.framework.TestCase; import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.commons.lang3.StringUtils; @@ -18,7 +19,6 @@ import org.neo4j.graphdb.QueryExecutionException; import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.ResourceIterator; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; import org.xmlunit.builder.DiffBuilder; diff --git a/core/src/test/java/apoc/export/json/ImportJsonTest.java b/core/src/test/java/apoc/export/json/ImportJsonTest.java index 0e23f4b68..0a6424435 100644 --- a/core/src/test/java/apoc/export/json/ImportJsonTest.java +++ b/core/src/test/java/apoc/export/json/ImportJsonTest.java @@ -5,6 +5,7 @@ import apoc.util.JsonUtil; import apoc.util.TestUtil; import apoc.util.Util; +import apoc.util.collection.Iterables; import junit.framework.TestCase; import org.apache.commons.lang.exception.ExceptionUtils; import apoc.util.Utils; @@ -19,7 +20,6 @@ import org.neo4j.graphdb.ResourceIterator; import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.spatial.Point; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; import org.neo4j.values.storable.CoordinateReferenceSystem; diff --git a/core/src/test/java/apoc/graph/GraphsTest.java b/core/src/test/java/apoc/graph/GraphsTest.java index 23336e841..83fc6bad3 100644 --- a/core/src/test/java/apoc/graph/GraphsTest.java +++ b/core/src/test/java/apoc/graph/GraphsTest.java @@ -4,6 +4,7 @@ import apoc.util.JsonUtil; import apoc.util.TestUtil; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.exception.ExceptionUtils; import org.junit.Before; @@ -15,7 +16,6 @@ import org.neo4j.graphdb.QueryExecutionException; import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.RelationshipType; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/load/LoadJsonTest.java b/core/src/test/java/apoc/load/LoadJsonTest.java index 6342ad3be..97cfc8f6a 100644 --- a/core/src/test/java/apoc/load/LoadJsonTest.java +++ b/core/src/test/java/apoc/load/LoadJsonTest.java @@ -4,6 +4,7 @@ import apoc.util.JsonUtil; import apoc.util.TestUtil; import apoc.util.Util; +import apoc.util.collection.Iterators; import org.apache.commons.lang.exception.ExceptionUtils; import inet.ipaddr.IPAddressString; import org.junit.*; @@ -14,7 +15,6 @@ import org.neo4j.configuration.GraphDatabaseInternalSettings; import org.neo4j.graphdb.QueryExecutionException; import org.neo4j.graphdb.Result; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/load/XmlTest.java b/core/src/test/java/apoc/load/XmlTest.java index 61ab8ad21..4137196d4 100644 --- a/core/src/test/java/apoc/load/XmlTest.java +++ b/core/src/test/java/apoc/load/XmlTest.java @@ -2,6 +2,8 @@ import apoc.util.CompressionAlgo; import apoc.util.TestUtil; +import apoc.util.collection.Iterables; +import apoc.util.collection.Iterators; import apoc.xml.XmlTestUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.exception.ExceptionUtils; @@ -11,8 +13,6 @@ import org.junit.rules.ExpectedException; import org.neo4j.graphdb.QueryExecutionException; import org.neo4j.graphdb.ResourceIterator; -import org.neo4j.internal.helpers.collection.Iterables; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; import org.xml.sax.SAXParseException; diff --git a/core/src/test/java/apoc/lock/LockTest.java b/core/src/test/java/apoc/lock/LockTest.java index f20e8cf14..ce8a1b0b4 100644 --- a/core/src/test/java/apoc/lock/LockTest.java +++ b/core/src/test/java/apoc/lock/LockTest.java @@ -1,13 +1,13 @@ package apoc.lock; import apoc.util.TestUtil; +import apoc.util.collection.Iterators; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.neo4j.configuration.GraphDatabaseSettings; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.kernel.impl.locking.LockAcquisitionTimeoutException; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/log/Neo4jLogStreamTest.java b/core/src/test/java/apoc/log/Neo4jLogStreamTest.java index d5f61a067..2778b72d7 100644 --- a/core/src/test/java/apoc/log/Neo4jLogStreamTest.java +++ b/core/src/test/java/apoc/log/Neo4jLogStreamTest.java @@ -1,12 +1,12 @@ package apoc.log; import apoc.util.TestUtil; +import apoc.util.collection.Iterators; import org.junit.Before; import org.junit.Test; import org.neo4j.configuration.GraphDatabaseSettings; import org.neo4j.dbms.api.DatabaseManagementService; import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.TestDatabaseManagementServiceBuilder; import java.nio.file.Paths; diff --git a/core/src/test/java/apoc/map/MapsTest.java b/core/src/test/java/apoc/map/MapsTest.java index 86b35902a..571450922 100644 --- a/core/src/test/java/apoc/map/MapsTest.java +++ b/core/src/test/java/apoc/map/MapsTest.java @@ -12,11 +12,11 @@ import java.util.Map; import static apoc.util.MapUtil.map; +import static apoc.util.collection.Iterators.asSet; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static org.junit.Assert.assertEquals; -import static org.neo4j.internal.helpers.collection.Iterators.asSet; /** * @author mh diff --git a/core/src/test/java/apoc/merge/MergeTest.java b/core/src/test/java/apoc/merge/MergeTest.java index 6c01d3ee4..760ae5502 100644 --- a/core/src/test/java/apoc/merge/MergeTest.java +++ b/core/src/test/java/apoc/merge/MergeTest.java @@ -2,11 +2,11 @@ import apoc.util.MapUtil; import apoc.util.TestUtil; +import apoc.util.collection.Iterators; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.neo4j.graphdb.*; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/meta/MetaTest.java b/core/src/test/java/apoc/meta/MetaTest.java index 703279cba..81c3c6516 100644 --- a/core/src/test/java/apoc/meta/MetaTest.java +++ b/core/src/test/java/apoc/meta/MetaTest.java @@ -4,6 +4,7 @@ import apoc.util.MapUtil; import apoc.util.TestUtil; import apoc.util.Util; +import apoc.util.collection.Iterables; import org.apache.commons.io.IOUtils; import org.assertj.core.api.Assertions; import org.junit.Assert; @@ -19,7 +20,6 @@ import org.neo4j.graphdb.RelationshipType; import org.neo4j.graphdb.Result; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; import org.neo4j.values.storable.CoordinateReferenceSystem; @@ -1601,7 +1601,7 @@ public void testRelTypePropertiesMovies() throws Exception { final String query = IOUtils.toString(new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream("movies.cypher"))); db.executeTransactionally(query); - + TestUtil.testResult( db, "CALL apoc.meta.relTypeProperties($config)", Map.of("config", Map.of("includeRels", List.of("REVIEWED"))), r -> { final Set> actual = r.stream().collect(Collectors.toSet()); diff --git a/core/src/test/java/apoc/nodes/GroupingTest.java b/core/src/test/java/apoc/nodes/GroupingTest.java index f0c8eebf8..69eb61490 100644 --- a/core/src/test/java/apoc/nodes/GroupingTest.java +++ b/core/src/test/java/apoc/nodes/GroupingTest.java @@ -1,13 +1,13 @@ package apoc.nodes; import apoc.util.TestUtil; +import apoc.util.collection.Iterators; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.neo4j.driver.internal.util.Iterables; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Relationship; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/nodes/NodesTest.java b/core/src/test/java/apoc/nodes/NodesTest.java index 9543c9985..fade7b22b 100644 --- a/core/src/test/java/apoc/nodes/NodesTest.java +++ b/core/src/test/java/apoc/nodes/NodesTest.java @@ -5,6 +5,8 @@ import apoc.result.VirtualRelationship; import apoc.util.TestUtil; import apoc.util.Util; +import apoc.util.collection.Iterables; +import apoc.util.collection.Iterators; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -12,8 +14,6 @@ import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Path; -import org.neo4j.internal.helpers.collection.Iterables; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; @@ -27,6 +27,7 @@ import static apoc.nodes.NodesConfig.MAX_DEPTH_KEY; import static apoc.nodes.NodesConfig.REL_TYPES_KEY; import static apoc.util.Util.map; +import static apoc.util.collection.Iterators.asSet; import static java.util.Arrays.asList; import static java.util.Collections.emptyMap; import static java.util.Collections.singletonList; @@ -36,7 +37,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.neo4j.graphdb.Label.label; -import static org.neo4j.internal.helpers.collection.Iterators.asSet; /** * @author mh diff --git a/core/src/test/java/apoc/path/ExpandPathTest.java b/core/src/test/java/apoc/path/ExpandPathTest.java index bee66348a..88d473c9b 100644 --- a/core/src/test/java/apoc/path/ExpandPathTest.java +++ b/core/src/test/java/apoc/path/ExpandPathTest.java @@ -2,6 +2,7 @@ import apoc.util.TestUtil; import apoc.util.Util; +import apoc.util.collection.Iterators; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.After; @@ -11,7 +12,6 @@ import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Path; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.internal.helpers.collection.MapUtil; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/path/NodeFilterTest.java b/core/src/test/java/apoc/path/NodeFilterTest.java index 4b3475f13..1cf555394 100644 --- a/core/src/test/java/apoc/path/NodeFilterTest.java +++ b/core/src/test/java/apoc/path/NodeFilterTest.java @@ -2,13 +2,13 @@ import apoc.util.TestUtil; import apoc.util.Util; +import apoc.util.collection.Iterators; import org.junit.After; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/path/RelSequenceTest.java b/core/src/test/java/apoc/path/RelSequenceTest.java index 458104bba..2f98bbf74 100644 --- a/core/src/test/java/apoc/path/RelSequenceTest.java +++ b/core/src/test/java/apoc/path/RelSequenceTest.java @@ -2,11 +2,11 @@ import apoc.util.TestUtil; import apoc.util.Util; +import apoc.util.collection.Iterators; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/periodic/PeriodicTest.java b/core/src/test/java/apoc/periodic/PeriodicTest.java index 4fe51ee60..4521bedd0 100644 --- a/core/src/test/java/apoc/periodic/PeriodicTest.java +++ b/core/src/test/java/apoc/periodic/PeriodicTest.java @@ -2,6 +2,7 @@ import apoc.util.MapUtil; import apoc.util.TestUtil; +import apoc.util.collection.Iterators; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -13,7 +14,6 @@ import org.neo4j.graphdb.schema.ConstraintDefinition; import org.neo4j.graphdb.schema.IndexDefinition; import org.neo4j.graphdb.schema.Schema; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.kernel.api.KernelTransactionHandle; import org.neo4j.kernel.impl.api.KernelTransactions; import org.neo4j.kernel.internal.GraphDatabaseAPI; diff --git a/core/src/test/java/apoc/refactor/GraphRefactoringTest.java b/core/src/test/java/apoc/refactor/GraphRefactoringTest.java index a7c2e71e3..ac5e91acb 100644 --- a/core/src/test/java/apoc/refactor/GraphRefactoringTest.java +++ b/core/src/test/java/apoc/refactor/GraphRefactoringTest.java @@ -3,6 +3,7 @@ import apoc.util.ArrayBackedList; import apoc.util.TestUtil; import apoc.util.Util; +import apoc.util.collection.Iterators; import org.apache.commons.collections4.IteratorUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.hamcrest.Matchers; @@ -17,7 +18,6 @@ import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.RelationshipType; import org.neo4j.graphdb.ResourceIterator; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/schema/SchemasTest.java b/core/src/test/java/apoc/schema/SchemasTest.java index a8effe2a2..488d861bb 100644 --- a/core/src/test/java/apoc/schema/SchemasTest.java +++ b/core/src/test/java/apoc/schema/SchemasTest.java @@ -1,5 +1,6 @@ package apoc.schema; +import apoc.util.collection.Iterables; import org.apache.commons.lang.exception.ExceptionUtils; import org.assertj.core.api.Assertions; import org.junit.Before; @@ -20,7 +21,6 @@ import org.neo4j.graphdb.schema.ConstraintType; import org.neo4j.graphdb.schema.IndexDefinition; import org.neo4j.graphdb.schema.Schema; -import org.neo4j.internal.helpers.collection.Iterables; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/text/StringsTest.java b/core/src/test/java/apoc/text/StringsTest.java index a93442bb3..1ff048921 100644 --- a/core/src/test/java/apoc/text/StringsTest.java +++ b/core/src/test/java/apoc/text/StringsTest.java @@ -2,6 +2,7 @@ import apoc.util.TestUtil; import apoc.util.Util; +import apoc.util.collection.Iterators; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Rule; @@ -11,7 +12,6 @@ import org.neo4j.graphdb.Node; import org.neo4j.graphdb.QueryExecutionException; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/trigger/TriggerRestartTest.java b/core/src/test/java/apoc/trigger/TriggerRestartTest.java index d89194f13..e7d32198b 100644 --- a/core/src/test/java/apoc/trigger/TriggerRestartTest.java +++ b/core/src/test/java/apoc/trigger/TriggerRestartTest.java @@ -2,6 +2,7 @@ import apoc.ApocConfig; import apoc.util.TestUtil; +import apoc.util.collection.Iterators; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -10,7 +11,6 @@ import org.neo4j.configuration.GraphDatabaseSettings; import org.neo4j.dbms.api.DatabaseManagementService; import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.test.TestDatabaseManagementServiceBuilder; import java.util.Collections; diff --git a/test-utils/src/main/java/apoc/algo/AlgoUtil.java b/test-utils/src/main/java/apoc/algo/AlgoUtil.java index 9669929ff..800516b6f 100644 --- a/test-utils/src/main/java/apoc/algo/AlgoUtil.java +++ b/test-utils/src/main/java/apoc/algo/AlgoUtil.java @@ -1,9 +1,9 @@ package apoc.algo; +import apoc.util.collection.Iterables; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Path; import org.neo4j.graphdb.Result; -import org.neo4j.internal.helpers.collection.Iterables; import java.util.List; import java.util.Map; diff --git a/test-utils/src/main/java/apoc/periodic/PeriodicTestUtils.java b/test-utils/src/main/java/apoc/periodic/PeriodicTestUtils.java index af925b627..66d58d88a 100644 --- a/test-utils/src/main/java/apoc/periodic/PeriodicTestUtils.java +++ b/test-utils/src/main/java/apoc/periodic/PeriodicTestUtils.java @@ -1,7 +1,7 @@ package apoc.periodic; +import apoc.util.collection.Iterators; import org.neo4j.common.DependencyResolver; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.kernel.impl.api.KernelTransactions; import org.neo4j.kernel.internal.GraphDatabaseAPI; diff --git a/test-utils/src/main/java/apoc/util/TestUtil.java b/test-utils/src/main/java/apoc/util/TestUtil.java index ed4ae4ef2..8679232c1 100644 --- a/test-utils/src/main/java/apoc/util/TestUtil.java +++ b/test-utils/src/main/java/apoc/util/TestUtil.java @@ -1,5 +1,7 @@ package apoc.util; +import apoc.util.collection.Iterables; +import apoc.util.collection.Iterators; import com.google.common.io.Files; import org.apache.commons.io.FileUtils; import org.hamcrest.Matcher; @@ -8,8 +10,6 @@ import org.neo4j.graphdb.ResourceIterator; import org.neo4j.graphdb.Result; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Iterables; -import org.neo4j.internal.helpers.collection.Iterators; import org.neo4j.kernel.api.procedure.GlobalProcedures; import org.neo4j.kernel.internal.GraphDatabaseAPI; From fbb6999d52ec9850d9a0b9cbf444a6f2a78abcf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louise=20S=C3=B6derstr=C3=B6m?= Date: Thu, 15 Sep 2022 14:47:27 +0200 Subject: [PATCH 3/9] Use apoc MapUtil instead of Neo4j one --- common/src/main/java/apoc/result/VirtualGraph.java | 2 +- common/src/main/java/apoc/trigger/TriggerHandler.java | 2 +- .../java/apoc/graph/document/builder/DocumentToGraphTest.java | 2 +- core/src/test/java/apoc/convert/ConvertJsonTest.java | 2 +- core/src/test/java/apoc/hashing/FingerprintingTest.java | 2 +- core/src/test/java/apoc/load/XmlTest.java | 2 +- core/src/test/java/apoc/path/ExpandPathTest.java | 2 +- core/src/test/java/apoc/periodic/PeriodicTest.java | 2 +- core/src/test/java/apoc/trigger/TriggerTest.java | 2 +- test-utils/src/main/java/apoc/xml/XmlTestUtils.java | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/common/src/main/java/apoc/result/VirtualGraph.java b/common/src/main/java/apoc/result/VirtualGraph.java index 814bd314c..74c998354 100644 --- a/common/src/main/java/apoc/result/VirtualGraph.java +++ b/common/src/main/java/apoc/result/VirtualGraph.java @@ -1,8 +1,8 @@ package apoc.result; +import apoc.util.MapUtil; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Relationship; -import org.neo4j.internal.helpers.collection.MapUtil; import java.util.Collection; import java.util.Map; diff --git a/common/src/main/java/apoc/trigger/TriggerHandler.java b/common/src/main/java/apoc/trigger/TriggerHandler.java index a0c7eebf8..7c0785709 100644 --- a/common/src/main/java/apoc/trigger/TriggerHandler.java +++ b/common/src/main/java/apoc/trigger/TriggerHandler.java @@ -4,6 +4,7 @@ import apoc.Pools; import apoc.SystemLabels; import apoc.SystemPropertyKeys; +import apoc.util.MapUtil; import apoc.util.collection.Iterators; import apoc.util.collection.Pair; import apoc.util.Util; @@ -15,7 +16,6 @@ import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.event.TransactionData; import org.neo4j.graphdb.event.TransactionEventListener; -import org.neo4j.internal.helpers.collection.MapUtil; import org.neo4j.internal.kernel.api.exceptions.ProcedureException; import org.neo4j.kernel.api.procedure.Context; import org.neo4j.kernel.api.procedure.GlobalProcedures; diff --git a/common/src/test/java/apoc/graph/document/builder/DocumentToGraphTest.java b/common/src/test/java/apoc/graph/document/builder/DocumentToGraphTest.java index 0fdb51690..fa6f6d429 100644 --- a/common/src/test/java/apoc/graph/document/builder/DocumentToGraphTest.java +++ b/common/src/test/java/apoc/graph/document/builder/DocumentToGraphTest.java @@ -4,10 +4,10 @@ import apoc.result.VirtualGraph; import apoc.result.VirtualNode; import apoc.result.VirtualRelationship; +import apoc.util.MapUtil; import org.junit.Test; import org.neo4j.graphdb.Label; import org.neo4j.graphdb.RelationshipType; -import org.neo4j.internal.helpers.collection.MapUtil; import java.util.*; diff --git a/core/src/test/java/apoc/convert/ConvertJsonTest.java b/core/src/test/java/apoc/convert/ConvertJsonTest.java index b8b222245..4070f31ef 100644 --- a/core/src/test/java/apoc/convert/ConvertJsonTest.java +++ b/core/src/test/java/apoc/convert/ConvertJsonTest.java @@ -1,5 +1,6 @@ package apoc.convert; +import apoc.util.MapUtil; import apoc.util.TestUtil; import apoc.util.Util; import junit.framework.TestCase; @@ -15,7 +16,6 @@ import org.neo4j.graphdb.Node; import org.neo4j.graphdb.QueryExecutionException; import org.neo4j.graphdb.Result; -import org.neo4j.internal.helpers.collection.MapUtil; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/hashing/FingerprintingTest.java b/core/src/test/java/apoc/hashing/FingerprintingTest.java index 5b208a382..bd7ce43b2 100644 --- a/core/src/test/java/apoc/hashing/FingerprintingTest.java +++ b/core/src/test/java/apoc/hashing/FingerprintingTest.java @@ -19,12 +19,12 @@ import java.util.Map; import java.util.Set; +import static apoc.util.MapUtil.map; import static java.util.Collections.EMPTY_LIST; import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -import static org.neo4j.internal.helpers.collection.MapUtil.map; public class FingerprintingTest { diff --git a/core/src/test/java/apoc/load/XmlTest.java b/core/src/test/java/apoc/load/XmlTest.java index 4137196d4..37bc01493 100644 --- a/core/src/test/java/apoc/load/XmlTest.java +++ b/core/src/test/java/apoc/load/XmlTest.java @@ -30,6 +30,7 @@ import static apoc.ApocConfig.apocConfig; import static apoc.util.BinaryTestUtil.fileToBinary; import static apoc.util.CompressionConfig.COMPRESSION; +import static apoc.util.MapUtil.map; import static apoc.util.TestUtil.*; import static java.util.Arrays.asList; import static org.hamcrest.CoreMatchers.containsString; @@ -38,7 +39,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.neo4j.internal.helpers.collection.MapUtil.map; public class XmlTest { public static final String FILE_SHORTENED = "src/test/resources/xml/humboldt_soemmering01_1791.TEI-P5-shortened.xml"; diff --git a/core/src/test/java/apoc/path/ExpandPathTest.java b/core/src/test/java/apoc/path/ExpandPathTest.java index 88d473c9b..607fa47d7 100644 --- a/core/src/test/java/apoc/path/ExpandPathTest.java +++ b/core/src/test/java/apoc/path/ExpandPathTest.java @@ -1,5 +1,6 @@ package apoc.path; +import apoc.util.MapUtil; import apoc.util.TestUtil; import apoc.util.Util; import apoc.util.collection.Iterators; @@ -12,7 +13,6 @@ import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Path; import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.MapUtil; import org.neo4j.test.rule.DbmsRule; import org.neo4j.test.rule.ImpermanentDbmsRule; diff --git a/core/src/test/java/apoc/periodic/PeriodicTest.java b/core/src/test/java/apoc/periodic/PeriodicTest.java index 4521bedd0..618149e8e 100644 --- a/core/src/test/java/apoc/periodic/PeriodicTest.java +++ b/core/src/test/java/apoc/periodic/PeriodicTest.java @@ -199,7 +199,7 @@ public void terminateIterateShouldNotFailonShutdown() throws Exception { "'unwind range(0,$totalNumberOfNodes) as i return i', " + "'create (p:Person{name:\"person_\" + i})', " + "{batchSize:$batchSizeCreate, parallel:true, params: {totalNumberOfNodes: $totalNumberOfNodes}})", - org.neo4j.internal.helpers.collection.MapUtil.map( + MapUtil.map( "totalNumberOfNodes", totalNumberOfNodes, "batchSizeCreate", batchSizeCreate )); diff --git a/core/src/test/java/apoc/trigger/TriggerTest.java b/core/src/test/java/apoc/trigger/TriggerTest.java index 2a9e84385..6988bfb00 100644 --- a/core/src/test/java/apoc/trigger/TriggerTest.java +++ b/core/src/test/java/apoc/trigger/TriggerTest.java @@ -22,10 +22,10 @@ import static apoc.ApocConfig.APOC_TRIGGER_ENABLED; import static apoc.ApocConfig.apocConfig; +import static apoc.util.MapUtil.map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.neo4j.configuration.GraphDatabaseSettings.procedure_unrestricted; -import static org.neo4j.internal.helpers.collection.MapUtil.map; /** * @author mh diff --git a/test-utils/src/main/java/apoc/xml/XmlTestUtils.java b/test-utils/src/main/java/apoc/xml/XmlTestUtils.java index b84b3106b..0ee24ef5c 100644 --- a/test-utils/src/main/java/apoc/xml/XmlTestUtils.java +++ b/test-utils/src/main/java/apoc/xml/XmlTestUtils.java @@ -3,8 +3,8 @@ import java.util.Arrays; import java.util.Map; +import static apoc.util.MapUtil.map; import static java.util.Arrays.asList; -import static org.neo4j.internal.helpers.collection.MapUtil.map; public class XmlTestUtils { From 5088d3d83a362546664c0796bd730a075cede723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louise=20S=C3=B6derstr=C3=B6m?= Date: Thu, 15 Sep 2022 15:13:28 +0200 Subject: [PATCH 4/9] Copy over rest of Neo4j helpers --- .../main/java/apoc/result/VirtualNode.java | 2 +- .../main/java/apoc/result/WrappedNode.java | 2 +- .../util/collection/FilteringIterable.java | 25 ++++++ .../util/collection/FilteringIterator.java | 32 ++++++++ .../collection/NestingResourceIterator.java | 39 +++++++++ .../PrefetchingResourceIterator.java | 1 - .../collection/ResourceClosingIterator.java | 79 +++++++++++++++++++ .../path/RelationshipSequenceExpander.java | 4 +- 8 files changed, 179 insertions(+), 5 deletions(-) create mode 100644 common/src/main/java/apoc/util/collection/FilteringIterable.java create mode 100644 common/src/main/java/apoc/util/collection/FilteringIterator.java create mode 100644 common/src/main/java/apoc/util/collection/NestingResourceIterator.java create mode 100644 common/src/main/java/apoc/util/collection/ResourceClosingIterator.java diff --git a/common/src/main/java/apoc/result/VirtualNode.java b/common/src/main/java/apoc/result/VirtualNode.java index 36c5d6e39..72c583428 100644 --- a/common/src/main/java/apoc/result/VirtualNode.java +++ b/common/src/main/java/apoc/result/VirtualNode.java @@ -1,9 +1,9 @@ package apoc.result; import apoc.util.Util; +import apoc.util.collection.FilteringIterable; import apoc.util.collection.Iterables; import org.neo4j.graphdb.*; -import org.neo4j.internal.helpers.collection.FilteringIterable; import java.util.*; import java.util.concurrent.atomic.AtomicLong; diff --git a/common/src/main/java/apoc/result/WrappedNode.java b/common/src/main/java/apoc/result/WrappedNode.java index adf221dac..1f42f52bc 100644 --- a/common/src/main/java/apoc/result/WrappedNode.java +++ b/common/src/main/java/apoc/result/WrappedNode.java @@ -1,8 +1,8 @@ package apoc.result; +import apoc.util.collection.FilteringIterable; import apoc.util.collection.Iterables; import org.neo4j.graphdb.*; -import org.neo4j.internal.helpers.collection.FilteringIterable; import java.util.*; import java.util.concurrent.atomic.AtomicLong; diff --git a/common/src/main/java/apoc/util/collection/FilteringIterable.java b/common/src/main/java/apoc/util/collection/FilteringIterable.java new file mode 100644 index 000000000..7007070b0 --- /dev/null +++ b/common/src/main/java/apoc/util/collection/FilteringIterable.java @@ -0,0 +1,25 @@ +package apoc.util.collection; + +import java.util.Iterator; +import java.util.function.Predicate; + +/** + * An iterable which filters another iterable, only letting items with certain + * criteria pass through. All iteration/filtering is done lazily. + * + * @param the type of items in the iteration. + */ +public class FilteringIterable implements Iterable { + private final Iterable source; + private final Predicate predicate; + + public FilteringIterable(Iterable source, Predicate predicate) { + this.source = source; + this.predicate = predicate; + } + + @Override + public Iterator iterator() { + return new FilteringIterator<>(source.iterator(), predicate); + } +} \ No newline at end of file diff --git a/common/src/main/java/apoc/util/collection/FilteringIterator.java b/common/src/main/java/apoc/util/collection/FilteringIterator.java new file mode 100644 index 000000000..32f252639 --- /dev/null +++ b/common/src/main/java/apoc/util/collection/FilteringIterator.java @@ -0,0 +1,32 @@ +package apoc.util.collection; + +import java.util.Iterator; +import java.util.function.Predicate; + +/** + * An iterator which filters another iterator, only letting items with certain + * criteria pass through. All iteration/filtering is done lazily. + * + * @param the type of items in the iteration. + */ +public class FilteringIterator extends PrefetchingIterator +{ + private final Iterator source; + private final Predicate predicate; + + public FilteringIterator(Iterator source, Predicate predicate) { + this.source = source; + this.predicate = predicate; + } + + @Override + protected T fetchNextOrNull() { + while (source.hasNext()) { + T testItem = source.next(); + if (predicate.test(testItem)) { + return testItem; + } + } + return null; + } +} diff --git a/common/src/main/java/apoc/util/collection/NestingResourceIterator.java b/common/src/main/java/apoc/util/collection/NestingResourceIterator.java new file mode 100644 index 000000000..c692d4cfb --- /dev/null +++ b/common/src/main/java/apoc/util/collection/NestingResourceIterator.java @@ -0,0 +1,39 @@ +package apoc.util.collection; + + +import java.util.Iterator; +import org.neo4j.graphdb.ResourceIterator; + +public abstract class NestingResourceIterator extends PrefetchingResourceIterator +{ + private final Iterator source; + private ResourceIterator currentNestedIterator; + + protected NestingResourceIterator(Iterator source) { + this.source = source; + } + + protected abstract ResourceIterator createNestedIterator(U item); + + @Override + protected T fetchNextOrNull() { + if (currentNestedIterator == null || !currentNestedIterator.hasNext()) { + while (source.hasNext()) { + U currentSurfaceItem = source.next(); + close(); + currentNestedIterator = createNestedIterator(currentSurfaceItem); + if (currentNestedIterator.hasNext()) { + break; + } + } + } + return currentNestedIterator != null && currentNestedIterator.hasNext() ? currentNestedIterator.next() : null; + } + + @Override + public void close() { + if (currentNestedIterator != null) { + currentNestedIterator.close(); + } + } +} diff --git a/common/src/main/java/apoc/util/collection/PrefetchingResourceIterator.java b/common/src/main/java/apoc/util/collection/PrefetchingResourceIterator.java index e6681ac27..90e0d6227 100644 --- a/common/src/main/java/apoc/util/collection/PrefetchingResourceIterator.java +++ b/common/src/main/java/apoc/util/collection/PrefetchingResourceIterator.java @@ -1,6 +1,5 @@ package apoc.util.collection; import org.neo4j.graphdb.ResourceIterator; -import org.neo4j.internal.helpers.collection.PrefetchingIterator; public abstract class PrefetchingResourceIterator extends PrefetchingIterator implements ResourceIterator {} diff --git a/common/src/main/java/apoc/util/collection/ResourceClosingIterator.java b/common/src/main/java/apoc/util/collection/ResourceClosingIterator.java new file mode 100644 index 000000000..1f036be19 --- /dev/null +++ b/common/src/main/java/apoc/util/collection/ResourceClosingIterator.java @@ -0,0 +1,79 @@ +package apoc.util.collection; + + +import java.util.Iterator; +import java.util.NoSuchElementException; +import org.neo4j.graphdb.Resource; +import org.neo4j.graphdb.ResourceIterable; +import org.neo4j.graphdb.ResourceIterator; +import org.neo4j.graphdb.ResourceUtils; + +public abstract class ResourceClosingIterator implements ResourceIterator { + public static ResourceIterator newResourceIterator(Iterator iterator, Resource... resources) { + return new ResourceClosingIterator<>(iterator, resources) { + @Override + public R map(R elem) { + return elem; + } + }; + } + + /** + * Return a {@link ResourceIterator} for the provided {@code iterable} that will also close + * this {@code iterable} when the returned iterator is itself closed. Please note, it is + * much preferred to explicitly close the {@link ResourceIterable} but this utility + * provides a way of cleaning up resources when the {@code iterable} is never exposed to + * client code; for example when the {@link ResourceIterator} is the return-type of a method + * call. + * + * @param iterable the iterable to provider the iterator + * @param the type of elements in the given iterable + * @return the iterator for the provided {@code iterable} + */ + public static ResourceIterator fromResourceIterable(ResourceIterable iterable) { + ResourceIterator iterator = iterable.iterator(); + return newResourceIterator(iterator, iterator, iterable); + } + + private Resource[] resources; + private final Iterator iterator; + + ResourceClosingIterator(Iterator iterator, Resource... resources) { + this.resources = resources; + this.iterator = iterator; + } + + @Override + public void close() { + if (resources != null) { + ResourceUtils.closeAll(resources); + resources = null; + } + } + + @Override + public boolean hasNext() { + boolean hasNext = iterator.hasNext(); + if (!hasNext) { + close(); + } + return hasNext; + } + + public abstract V map(T elem); + + @Override + public V next() { + try { + return map(iterator.next()); + } catch (NoSuchElementException e) { + close(); + throw e; + } + } + + @Override + public void remove() { + iterator.remove(); + } +} diff --git a/core/src/main/java/apoc/path/RelationshipSequenceExpander.java b/core/src/main/java/apoc/path/RelationshipSequenceExpander.java index fbe12fab7..528c1c0c8 100644 --- a/core/src/main/java/apoc/path/RelationshipSequenceExpander.java +++ b/core/src/main/java/apoc/path/RelationshipSequenceExpander.java @@ -2,7 +2,9 @@ import apoc.util.collection.Iterables; import apoc.util.collection.Iterators; +import apoc.util.collection.NestingResourceIterator; import apoc.util.collection.Pair; +import apoc.util.collection.ResourceClosingIterator; import java.util.ArrayList; import java.util.List; @@ -15,8 +17,6 @@ import org.neo4j.graphdb.ResourceIterable; import org.neo4j.graphdb.ResourceIterator; import org.neo4j.graphdb.traversal.BranchState; -import org.neo4j.internal.helpers.collection.NestingResourceIterator; -import org.neo4j.internal.helpers.collection.ResourceClosingIterator; /** * An expander for repeating sequences of relationships. The sequence provided should be a string consisting of From 290c8276cf7f1088407967400e3e7b44e42d216b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louise=20S=C3=B6derstr=C3=B6m?= Date: Fri, 16 Sep 2022 14:57:38 +0200 Subject: [PATCH 5/9] Remove unused benchmarking code This benchmarking code which used internal Neo4j APIs is unused and related to auto-indexing which does not exist in Neo4j anymore. --- .../apoc/AsyncIndexingGraphDatabaseState.java | 16 ------- .../src/jmh/java/apoc/GraphDatabaseState.java | 47 ------------------- .../apoc/IndexTrackingGraphDatabaseState.java | 28 ----------- .../jmh/java/apoc/IndexUpdateBenchmarks.java | 44 ----------------- .../apoc/SyncIndexingGraphDatabaseState.java | 12 ----- 5 files changed, 147 deletions(-) delete mode 100644 common/src/jmh/java/apoc/AsyncIndexingGraphDatabaseState.java delete mode 100644 common/src/jmh/java/apoc/GraphDatabaseState.java delete mode 100644 common/src/jmh/java/apoc/IndexTrackingGraphDatabaseState.java delete mode 100644 common/src/jmh/java/apoc/IndexUpdateBenchmarks.java delete mode 100644 common/src/jmh/java/apoc/SyncIndexingGraphDatabaseState.java diff --git a/common/src/jmh/java/apoc/AsyncIndexingGraphDatabaseState.java b/common/src/jmh/java/apoc/AsyncIndexingGraphDatabaseState.java deleted file mode 100644 index 16762b4f4..000000000 --- a/common/src/jmh/java/apoc/AsyncIndexingGraphDatabaseState.java +++ /dev/null @@ -1,16 +0,0 @@ -package apoc; - -import org.neo4j.internal.helpers.collection.MapUtil; - -import java.util.Map; - -public class AsyncIndexingGraphDatabaseState extends SyncIndexingGraphDatabaseState { - - @Override - public Map getGraphDatabaseConfig() { - return MapUtil.genericMap("apoc.autoIndex.enabled", "true", - "apoc.autoIndex.async", "true", - "apoc.autoIndex.configUpdateInterval", "-1"); - } - -} diff --git a/common/src/jmh/java/apoc/GraphDatabaseState.java b/common/src/jmh/java/apoc/GraphDatabaseState.java deleted file mode 100644 index aab83c044..000000000 --- a/common/src/jmh/java/apoc/GraphDatabaseState.java +++ /dev/null @@ -1,47 +0,0 @@ -package apoc; - -import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.helpers.collection.Iterables; -import org.neo4j.test.TestGraphDatabaseFactory; -import org.openjdk.jmh.annotations.*; - -import java.util.Collections; -import java.util.Map; - -@State(Scope.Benchmark) -public class GraphDatabaseState { - - - private GraphDatabaseService graphDatabaseService; - - public GraphDatabaseService getGraphDatabaseService() { - return graphDatabaseService; - } - - @Setup(Level.Invocation) - public final void setup() { - graphDatabaseService = new TestGraphDatabaseFactory().newImpermanentDatabaseBuilder() - .setConfig(getGraphDatabaseConfig()) - .newGraphDatabase(); - setupGraphDatabase(graphDatabaseService); - } - - @TearDown(Level.Invocation) - public final void tearDown() { - - try (Transaction tx = graphDatabaseService.beginTx()) { - long numberOfNodes = Iterables.count(graphDatabaseService.getAllNodes()); - tx.success(); - } - graphDatabaseService.shutdown(); - } - - public Map getGraphDatabaseConfig() { - return Collections.EMPTY_MAP; - } - - void setupGraphDatabase(GraphDatabaseService graphDatabaseService) { - } -} - diff --git a/common/src/jmh/java/apoc/IndexTrackingGraphDatabaseState.java b/common/src/jmh/java/apoc/IndexTrackingGraphDatabaseState.java deleted file mode 100644 index 7bdadbb68..000000000 --- a/common/src/jmh/java/apoc/IndexTrackingGraphDatabaseState.java +++ /dev/null @@ -1,28 +0,0 @@ -package apoc; - -import apoc.util.TestUtil; - -import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.internal.helpers.collection.MapUtil; -import org.neo4j.internal.kernel.api.exceptions.KernelException; - -import java.util.Map; - -public class IndexTrackingGraphDatabaseState extends GraphDatabaseState { - - @Override - public Map getGraphDatabaseConfig() { - return MapUtil.genericMap("apoc.autoIndex.enabled", "true", - "apoc.autoIndex.configUpdateInterval", "-1"); - } - - @Override - void setupGraphDatabase(GraphDatabaseService graphDatabaseService) { - try { - TestUtil.registerProcedure(getGraphDatabaseService(), FreeTextSearch.class); - //graphDatabaseService.execute("CALL apoc.index.addAllNodesExtended('person_index',{Person:['name']},{autoUpdate:true})"); - } catch (KernelException e) { - throw new RuntimeException(e); - } - } -} diff --git a/common/src/jmh/java/apoc/IndexUpdateBenchmarks.java b/common/src/jmh/java/apoc/IndexUpdateBenchmarks.java deleted file mode 100644 index 9222af54e..000000000 --- a/common/src/jmh/java/apoc/IndexUpdateBenchmarks.java +++ /dev/null @@ -1,44 +0,0 @@ -package apoc; - -import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.graphdb.Label; -import org.neo4j.graphdb.Node; -import org.neo4j.graphdb.Transaction; -import org.openjdk.jmh.annotations.Benchmark; - -public class IndexUpdateBenchmarks { - - @Benchmark - public void add10kNonIndexedNodes(GraphDatabaseState state) { - populateDb( state, 10000 ); - } - - @Benchmark - public void add10kNodesWithBackgroundUpdatesEnabled(IndexTrackingGraphDatabaseState state) { - populateDb( state, 10000 ); - } - - @Benchmark - public void add10kIndexedSyncNodes(SyncIndexingGraphDatabaseState state) { - populateDb( state, 10000 ); - } - - @Benchmark - public void add10kIndexedAsyncNodes(AsyncIndexingGraphDatabaseState state) { - populateDb( state, 10000 ); - } - - private void populateDb( GraphDatabaseState state, int numberOfNodes ) - { - final GraphDatabaseService db = state.getGraphDatabaseService(); - final Label label = Label.label("Person"); - try (Transaction tx = db.beginTx()) { - for (int i=0; i Date: Wed, 28 Sep 2022 14:59:53 +0200 Subject: [PATCH 6/9] Fix smaller review comments --- .../main/java/apoc/convert/ConvertUtils.java | 5 +- .../java/apoc/util/collection/Iterables.java | 5 -- .../java/apoc/util/collection/Iterators.java | 19 +------- .../apoc/util/collection/MapIterable.java | 48 ------------------- .../cypher/export/CypherResultSubGraph.java | 8 ++-- .../MultiStatementCypherSubGraphExporter.java | 4 +- core/src/main/java/apoc/nodes/Nodes.java | 4 +- 7 files changed, 11 insertions(+), 82 deletions(-) delete mode 100644 common/src/main/java/apoc/util/collection/MapIterable.java diff --git a/common/src/main/java/apoc/convert/ConvertUtils.java b/common/src/main/java/apoc/convert/ConvertUtils.java index bbf91e2f2..53f08f914 100644 --- a/common/src/main/java/apoc/convert/ConvertUtils.java +++ b/common/src/main/java/apoc/convert/ConvertUtils.java @@ -1,5 +1,6 @@ package apoc.convert; +import apoc.util.collection.Iterables; import apoc.util.collection.Iterators; import java.lang.reflect.Array; import java.util.ArrayList; @@ -18,8 +19,8 @@ public static List convertToList(Object list) { if (list == null) return null; else if (list instanceof List) return (List) list; else if (list instanceof Collection) return new ArrayList((Collection)list); - else if (list instanceof Iterable) return Iterators.addToCollection(((Iterable)list).iterator(),(List)new ArrayList<>(100)); - else if (list instanceof Iterator) return Iterators.addToCollection((Iterator)list,(List)new ArrayList<>(100)); + else if (list instanceof Iterable) return Iterables.asList((Iterable)list); + else if (list instanceof Iterator) return Iterators.asList((Iterator)list); else if (list.getClass().isArray()) { final Object[] objectArray; if (list.getClass().getComponentType().isPrimitive()) { diff --git a/common/src/main/java/apoc/util/collection/Iterables.java b/common/src/main/java/apoc/util/collection/Iterables.java index 2b5f1b729..aef6738f4 100644 --- a/common/src/main/java/apoc/util/collection/Iterables.java +++ b/common/src/main/java/apoc/util/collection/Iterables.java @@ -10,7 +10,6 @@ import java.util.NoSuchElementException; import java.util.Objects; import java.util.Set; -import java.util.function.Function; import java.util.stream.Stream; import org.neo4j.graphdb.Resource; import org.neo4j.graphdb.ResourceIterable; @@ -54,10 +53,6 @@ public static > C addAll(C collection, Iterable Iterable map(Function function, Iterable from) { - return new MapIterable<>(from, function); - } - @SafeVarargs public static Iterable iterable(C... items) { return Arrays.asList(items); diff --git a/common/src/main/java/apoc/util/collection/Iterators.java b/common/src/main/java/apoc/util/collection/Iterators.java index af5848619..8b8260fcc 100644 --- a/common/src/main/java/apoc/util/collection/Iterators.java +++ b/common/src/main/java/apoc/util/collection/Iterators.java @@ -112,7 +112,7 @@ private static T assertNotNull(Iterator iterator, T result) { * @return the {@code collection} which was passed in, now filled * with the items from {@code iterator}. */ - public static , T> C addToCollection(Iterator iterator, C collection) { + private static , T> C addToCollection(Iterator iterator, C collection) { try { while (iterator.hasNext()) { collection.add(iterator.next()); @@ -123,23 +123,6 @@ public static , T> C addToCollection(Iterator iterato } } - /** - * Convenience method for looping over an {@link Iterator}. Converts the - * {@link Iterator} to an {@link Iterable} by wrapping it in an - * {@link Iterable} that returns the {@link Iterator}. It breaks the - * contract of {@link Iterable} in that it returns the supplied iterator - * instance for each call to {@code iterator()} on the returned - * {@link Iterable} instance. This method exists to make it easy to use an - * {@link Iterator} in a for-loop. - * - * @param the type of items in the iterator. - * @param iterator the iterator to expose as an {@link Iterable}. - * @return the supplied iterator posing as an {@link Iterable}. - */ - public static Iterable loop(final Iterator iterator) { - return () -> iterator; - } - /** * Counts the number of items in the {@code iterator} by looping * through it. diff --git a/common/src/main/java/apoc/util/collection/MapIterable.java b/common/src/main/java/apoc/util/collection/MapIterable.java deleted file mode 100644 index 36ac6ff7e..000000000 --- a/common/src/main/java/apoc/util/collection/MapIterable.java +++ /dev/null @@ -1,48 +0,0 @@ -package apoc.util.collection; - - -import java.util.Iterator; -import java.util.function.Function; - -class MapIterable implements Iterable { - private final Iterable from; - private final Function function; - - MapIterable(Iterable from, Function function) { - this.from = from; - this.function = function; - } - - @Override - public Iterator iterator() { - return new MapIterator<>(from.iterator(), function); - } - - static class MapIterator implements Iterator { - private final Iterator fromIterator; - private final Function function; - - MapIterator(Iterator fromIterator, Function function) { - this.fromIterator = fromIterator; - this.function = function; - } - - @Override - public boolean hasNext() { - return fromIterator.hasNext(); - } - - @Override - public TO next() { - FROM from = fromIterator.next(); - - return function.apply(from); - } - - @Override - public void remove() { - fromIterator.remove(); - } - } -} - diff --git a/common/src/main/java/org/neo4j/cypher/export/CypherResultSubGraph.java b/common/src/main/java/org/neo4j/cypher/export/CypherResultSubGraph.java index bd2d03a8d..06a355984 100644 --- a/common/src/main/java/org/neo4j/cypher/export/CypherResultSubGraph.java +++ b/common/src/main/java/org/neo4j/cypher/export/CypherResultSubGraph.java @@ -1,7 +1,5 @@ package org.neo4j.cypher.export; -import static apoc.util.collection.Iterators.loop; - import apoc.util.collection.Iterables; import org.neo4j.graphdb.*; import org.neo4j.graphdb.schema.ConstraintDefinition; @@ -34,7 +32,7 @@ public void add( Node node ) void addNode( long id, Node data ) { nodes.put( id, data ); - labels.addAll( Iterables.addAll( new ArrayList<>(), data.getLabels() ) ); + labels.addAll( Iterables.asList( data.getLabels() ) ); } public void add( Relationship rel ) @@ -52,14 +50,14 @@ public static SubGraph from(Transaction tx, Result result, boolean addBetween) { final CypherResultSubGraph graph = new CypherResultSubGraph(); final List columns = result.columns(); - for ( Map row : loop( result ) ) + result.forEachRemaining( row -> { for ( String column : columns ) { final Object value = row.get( column ); graph.addToGraph( value ); } - } + } ); for ( IndexDefinition def : tx.schema().getIndexes() ) { if ( def.isNodeIndex() && def.getIndexType() != IndexType.LOOKUP ) diff --git a/core/src/main/java/apoc/export/cypher/MultiStatementCypherSubGraphExporter.java b/core/src/main/java/apoc/export/cypher/MultiStatementCypherSubGraphExporter.java index c557043e8..94f18c0e2 100644 --- a/core/src/main/java/apoc/export/cypher/MultiStatementCypherSubGraphExporter.java +++ b/core/src/main/java/apoc/export/cypher/MultiStatementCypherSubGraphExporter.java @@ -243,9 +243,9 @@ private List exportIndexes() { Iterable props = index.getPropertyKeys(); List tokenNames; if (isNodeIndex) { - tokenNames = Iterables.asList(Iterables.map(Label::name, index.getLabels())); + tokenNames = Iterables.stream(index.getLabels()).map(Label::name).collect(Collectors.toList()); } else { - tokenNames = Iterables.asList(Iterables.map(RelationshipType::name, index.getRelationshipTypes())); + tokenNames = Iterables.stream(index.getRelationshipTypes()).map(RelationshipType::name).collect(Collectors.toList()); } boolean inGraph = tokensInGraph(tokenNames); diff --git a/core/src/main/java/apoc/nodes/Nodes.java b/core/src/main/java/apoc/nodes/Nodes.java index f716a6eaa..df7d0d0b7 100644 --- a/core/src/main/java/apoc/nodes/Nodes.java +++ b/core/src/main/java/apoc/nodes/Nodes.java @@ -573,7 +573,7 @@ public long degreeOut(@Name("node") Node node, @Name(value = "types",defaultValu @Description("apoc.node.relationship.types(node, rel-direction-pattern) - returns a list of distinct relationship types") public List relationshipTypes(@Name("node") Node node, @Name(value = "types",defaultValue = "") String types) { if (node==null) return null; - List relTypes = Iterables.asList(Iterables.map(RelationshipType::name, node.getRelationshipTypes())); + List relTypes = Iterables.stream(node.getRelationshipTypes()).map(RelationshipType::name).collect(Collectors.toList()); if (types == null || types.isEmpty()) return relTypes; List result = new ArrayList<>(relTypes.size()); for (Pair p : parse(types)) { @@ -608,7 +608,7 @@ public List> nodesRelationshipTypes(@Name("ids") Object ids, @Description("apoc.node.relationships.exist(node, rel-direction-pattern) - returns a map with rel-pattern, boolean for the given relationship patterns") public Map relationshipExists(@Name("node") Node node, @Name(value = "types", defaultValue = "") String types) { if (node == null || types == null || types.isEmpty()) return null; - List relTypes = Iterables.asList(Iterables.map(RelationshipType::name, node.getRelationshipTypes())); + List relTypes = Iterables.stream(node.getRelationshipTypes()).map(RelationshipType::name).toList(); Map result = new HashMap<>(); for (Pair p : parse(types)) { String name = p.first().name(); From 029b29b87a8ed575600b0df9b87c6b05dbc46614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louise=20S=C3=B6derstr=C3=B6m?= Date: Thu, 29 Sep 2022 10:22:24 +0200 Subject: [PATCH 7/9] Use Pair from apache instead of Neo4j --- .../main/java/apoc/algo/PathFindingUtils.java | 14 +-- .../path/RelationshipTypeAndDirections.java | 6 +- .../java/apoc/periodic/PeriodicUtils.java | 2 +- .../java/apoc/trigger/TriggerHandler.java | 2 +- common/src/main/java/apoc/util/Util.java | 8 +- .../main/java/apoc/util/collection/Pair.java | 85 ------------------- .../RelationshipTypeAndDirectionsTest.java | 2 +- core/src/main/java/apoc/coll/Coll.java | 6 +- core/src/main/java/apoc/meta/Meta.java | 4 +- .../main/java/apoc/neighbors/Neighbors.java | 12 +-- core/src/main/java/apoc/nodes/Nodes.java | 22 ++--- .../path/RelationshipSequenceExpander.java | 6 +- .../src/main/java/apoc/periodic/Periodic.java | 6 +- .../java/apoc/refactor/util/RefactorUtil.java | 2 +- .../java/apoc/stats/DegreeDistribution.java | 6 +- core/src/main/java/apoc/text/Strings.java | 8 +- .../java/apoc/load/LoadCoreSecurityTest.java | 4 +- .../java/apoc/periodic/PeriodicUtilsTest.java | 30 +++---- core/src/test/java/apoc/util/UtilTest.java | 2 +- .../apoc/util/SensitivePathGenerator.java | 2 +- 20 files changed, 72 insertions(+), 157 deletions(-) delete mode 100644 common/src/main/java/apoc/util/collection/Pair.java diff --git a/common/src/main/java/apoc/algo/PathFindingUtils.java b/common/src/main/java/apoc/algo/PathFindingUtils.java index c44f33043..7e75cf954 100644 --- a/common/src/main/java/apoc/algo/PathFindingUtils.java +++ b/common/src/main/java/apoc/algo/PathFindingUtils.java @@ -1,7 +1,7 @@ package apoc.algo; import apoc.path.RelationshipTypeAndDirections; -import apoc.util.collection.Pair; +import org.apache.commons.lang3.tuple.Pair; import org.neo4j.graphalgo.EstimateEvaluator; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.Node; @@ -62,17 +62,17 @@ public static PathExpander buildPathExpander(String relationshipsAndDire PathExpanderBuilder builder = PathExpanderBuilder.empty(); for (Pair pair : RelationshipTypeAndDirections .parse(relationshipsAndDirections)) { - if (pair.first() == null) { - if (pair.other() == null) { + if (pair.getLeft() == null) { + if (pair.getRight() == null) { builder = PathExpanderBuilder.allTypesAndDirections(); } else { - builder = PathExpanderBuilder.allTypes(pair.other()); + builder = PathExpanderBuilder.allTypes(pair.getRight()); } } else { - if (pair.other() == null) { - builder = builder.add(pair.first()); + if (pair.getRight() == null) { + builder = builder.add(pair.getLeft()); } else { - builder = builder.add(pair.first(), pair.other()); + builder = builder.add(pair.getLeft(), pair.getRight()); } } } diff --git a/common/src/main/java/apoc/path/RelationshipTypeAndDirections.java b/common/src/main/java/apoc/path/RelationshipTypeAndDirections.java index e353cd817..b8bd32222 100644 --- a/common/src/main/java/apoc/path/RelationshipTypeAndDirections.java +++ b/common/src/main/java/apoc/path/RelationshipTypeAndDirections.java @@ -1,6 +1,6 @@ package apoc.path; -import apoc.util.collection.Pair; +import org.apache.commons.lang3.tuple.Pair; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.RelationshipType; @@ -20,8 +20,8 @@ public abstract class RelationshipTypeAndDirections { public static final char BACKTICK = '`'; public static String format(Pair typeAndDirection) { - String type = typeAndDirection.first().name(); - switch (typeAndDirection.other()) { + String type = typeAndDirection.getLeft().name(); + switch (typeAndDirection.getRight()) { case OUTGOING: return type + ">"; case INCOMING: diff --git a/common/src/main/java/apoc/periodic/PeriodicUtils.java b/common/src/main/java/apoc/periodic/PeriodicUtils.java index 22492b65a..cebf23643 100644 --- a/common/src/main/java/apoc/periodic/PeriodicUtils.java +++ b/common/src/main/java/apoc/periodic/PeriodicUtils.java @@ -1,9 +1,9 @@ package apoc.periodic; import apoc.Pools; -import apoc.util.collection.Pair; import apoc.util.Util; import org.apache.commons.lang3.exception.ExceptionUtils; +import org.apache.commons.lang3.tuple.Pair; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.QueryStatistics; import org.neo4j.graphdb.Transaction; diff --git a/common/src/main/java/apoc/trigger/TriggerHandler.java b/common/src/main/java/apoc/trigger/TriggerHandler.java index 7c0785709..a0802d6d6 100644 --- a/common/src/main/java/apoc/trigger/TriggerHandler.java +++ b/common/src/main/java/apoc/trigger/TriggerHandler.java @@ -6,8 +6,8 @@ import apoc.SystemPropertyKeys; import apoc.util.MapUtil; import apoc.util.collection.Iterators; -import apoc.util.collection.Pair; import apoc.util.Util; +import org.apache.commons.lang3.tuple.Pair; import org.neo4j.dbms.api.DatabaseManagementService; import org.neo4j.function.ThrowingFunction; import org.neo4j.graphdb.GraphDatabaseService; diff --git a/common/src/main/java/apoc/util/Util.java b/common/src/main/java/apoc/util/Util.java index 0bb49f265..13d3c00a9 100644 --- a/common/src/main/java/apoc/util/Util.java +++ b/common/src/main/java/apoc/util/Util.java @@ -8,11 +8,11 @@ import apoc.result.VirtualNode; import apoc.result.VirtualRelationship; import apoc.util.collection.Iterators; -import apoc.util.collection.Pair; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveInputStream; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; import org.eclipse.collections.api.iterator.LongIterator; import org.neo4j.logging.NullLog; import org.neo4j.values.storable.CoordinateReferenceSystem; @@ -963,11 +963,11 @@ public static List rebind(List entities, Transaction tx public static Node mergeNode(Transaction tx, Label primaryLabel, Label addtionalLabel, Pair... pairs) { - Node node = Iterators.singleOrNull(tx.findNodes(primaryLabel, pairs[0].first(), pairs[0].other()).stream() + Node node = Iterators.singleOrNull(tx.findNodes(primaryLabel, pairs[0].getLeft(), pairs[0].getRight()).stream() .filter(n -> addtionalLabel == null || n.hasLabel(addtionalLabel)) .filter( n -> { for (int i=1; i the type of the {@link #first() first value} of the pair. - * @param the type of the {@link #other() other value} of the pair. - */ -public abstract class Pair { - /** - * Create a new pair of objects. - * - * @param first the first object in the pair. - * @param other the other object in the pair. - * @param the type of the first object in the pair - * @param the type of the second object in the pair - * @return a new pair of the two parameters. - */ - public static Pair pair(final T1 first, final T2 other) { - return new Pair<>() { - @Override - public T1 first() { - return first; - } - - @Override - public T2 other() { - return other; - } - }; - } - - /** - * Alias of {@link #pair(Object, Object)}. - * @param first the first object in the pair. - * @param other the other object in the pair. - * @param the type of the first object in the pair - * @param the type of the second object in the pair - * @return a new pair of the two parameters. - */ - public static Pair of(final T1 first, final T2 other) { - return pair(first, other); - } - - Pair() { - // package private, limited number of subclasses - } - - /** - * @return the first object in the pair. - */ - public abstract T1 first(); - - /** - * @return the other object in the pair. - */ - public abstract T2 other(); - - @Override - public String toString() { - return "(" + first() + ", " + other() + ")"; - } - - @Override - public int hashCode() { - return (31 * hashCode(first())) | hashCode(other()); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof Pair that) { - return Objects.equals(this.other(), that.other()) && Objects.equals(this.first(), that.first()); - } - return false; - } - - private static int hashCode(Object obj) { - return obj == null ? 0 : obj.hashCode(); - } -} diff --git a/common/src/test/java/apoc/path/RelationshipTypeAndDirectionsTest.java b/common/src/test/java/apoc/path/RelationshipTypeAndDirectionsTest.java index cdc1e571d..50a90bb86 100644 --- a/common/src/test/java/apoc/path/RelationshipTypeAndDirectionsTest.java +++ b/common/src/test/java/apoc/path/RelationshipTypeAndDirectionsTest.java @@ -1,6 +1,6 @@ package apoc.path; -import apoc.util.collection.Pair; +import org.apache.commons.lang3.tuple.Pair; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; diff --git a/core/src/main/java/apoc/coll/Coll.java b/core/src/main/java/apoc/coll/Coll.java index 00ee40efc..3269f525e 100644 --- a/core/src/main/java/apoc/coll/Coll.java +++ b/core/src/main/java/apoc/coll/Coll.java @@ -1,9 +1,9 @@ package apoc.coll; import apoc.result.ListResult; -import apoc.util.collection.Pair; import com.google.common.util.concurrent.AtomicDouble; import org.apache.commons.lang3.mutable.MutableInt; +import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.math3.stat.descriptive.moment.StandardDeviation; import org.apache.commons.math3.util.Combinations; import org.neo4j.graphdb.GraphDatabaseService; @@ -853,12 +853,12 @@ public List> sortMulti(@Name("coll") List> int a = 0; for (Pair s : fields) { if (a != 0) break; - String name = s.first(); + String name = s.getLeft(); Comparable v1 = o1.get(name); Comparable v2 = o2.get(name); if (v1 != v2) { int cmp = (v1 == null) ? -1 : (v2 == null) ? 1 : v1.compareTo(v2); - a = (s.other()) ? cmp : -cmp; + a = (s.getRight()) ? cmp : -cmp; } } return a; diff --git a/core/src/main/java/apoc/meta/Meta.java b/core/src/main/java/apoc/meta/Meta.java index 9939a658c..04ce67e91 100644 --- a/core/src/main/java/apoc/meta/Meta.java +++ b/core/src/main/java/apoc/meta/Meta.java @@ -8,8 +8,8 @@ import apoc.result.VirtualRelationship; import apoc.util.MapUtil; import apoc.util.collection.Iterables; -import apoc.util.collection.Pair; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.tuple.Pair; import org.neo4j.cypher.export.CypherResultSubGraph; import org.neo4j.cypher.export.DatabaseSubGraph; import org.neo4j.cypher.export.SubGraph; @@ -261,7 +261,7 @@ public long count(@Name(value = "nodes", defaultValue = "[]") List nodes }) .flatMap(pair -> transaction.findNodes(label) .map(node -> { - if (!visitedNodes.contains(node.getId()) && node.hasRelationship(pair.first(), RelationshipType.withName(pair.other()))) { + if (!visitedNodes.contains(node.getId()) && node.hasRelationship(pair.getLeft(), RelationshipType.withName(pair.getRight()))) { visitedNodes.add(node.getId()); return 1L; } else { diff --git a/core/src/main/java/apoc/neighbors/Neighbors.java b/core/src/main/java/apoc/neighbors/Neighbors.java index e1c2e8da0..ea52939ae 100644 --- a/core/src/main/java/apoc/neighbors/Neighbors.java +++ b/core/src/main/java/apoc/neighbors/Neighbors.java @@ -4,7 +4,7 @@ import apoc.result.LongResult; import apoc.result.NodeListResult; import apoc.result.NodeResult; -import apoc.util.collection.Pair; +import org.apache.commons.lang3.tuple.Pair; import org.neo4j.graphdb.*; import org.neo4j.procedure.Context; import org.neo4j.procedure.Description; @@ -26,13 +26,13 @@ public class Neighbors { private Iterable getRelationshipsByTypeAndDirection(Node node, Pair typesAndDirection) { // as policy if both elements in the pair are null we return an empty result - if (typesAndDirection.first() == null) { - return typesAndDirection.other() == null ? Collections.emptyList() : node.getRelationships(typesAndDirection.other()); + if (typesAndDirection.getLeft() == null) { + return typesAndDirection.getRight() == null ? Collections.emptyList() : node.getRelationships(typesAndDirection.getRight()); } - if (typesAndDirection.other() == null) { - return typesAndDirection.first() == null ? Collections.emptyList() : node.getRelationships(typesAndDirection.first()); + if (typesAndDirection.getRight() == null) { + return typesAndDirection.getLeft() == null ? Collections.emptyList() : node.getRelationships(typesAndDirection.getLeft()); } - return node.getRelationships(typesAndDirection.other(), typesAndDirection.first()); + return node.getRelationships(typesAndDirection.getRight(), typesAndDirection.getLeft()); } @Procedure("apoc.neighbors.tohop") diff --git a/core/src/main/java/apoc/nodes/Nodes.java b/core/src/main/java/apoc/nodes/Nodes.java index df7d0d0b7..68692ba5b 100644 --- a/core/src/main/java/apoc/nodes/Nodes.java +++ b/core/src/main/java/apoc/nodes/Nodes.java @@ -12,8 +12,8 @@ import apoc.result.VirtualPath; import apoc.result.VirtualPathResult; import apoc.util.collection.Iterables; -import apoc.util.collection.Pair; import apoc.util.Util; +import org.apache.commons.lang3.tuple.Pair; import org.neo4j.graphalgo.BasicEvaluationContext; import org.neo4j.graphalgo.GraphAlgoFactory; import org.neo4j.graphalgo.PathFinder; @@ -183,8 +183,8 @@ public boolean hasRelationship(@Name("node") Node node, @Name(value = "types", d TokenRead tokenRead = ktx.tokenRead(); for (Pair pair : parse(types)) { - int typeId = tokenRead.relationshipType(pair.first().name()); - Direction direction = pair.other(); + int typeId = tokenRead.relationshipType(pair.getLeft().name()); + Direction direction = pair.getRight(); int count; switch (direction) { @@ -369,12 +369,12 @@ private int[][] typedDirections(TokenRead ops, List pair : pairs) { - int type = ops.relationshipType(pair.first().name()); + int type = ops.relationshipType(pair.getLeft().name()); if (type == -1) continue; - if (pair.other() != Direction.INCOMING) { + if (pair.getRight() != Direction.INCOMING) { result[outIdx][from++]= type; } - if (pair.other() != Direction.OUTGOING) { + if (pair.getRight() != Direction.OUTGOING) { result[inIdx][to++]= type; } } @@ -539,7 +539,7 @@ public long degree(@Name("node") Node node, @Name(value = "types",defaultValue = if (types==null || types.isEmpty()) return node.getDegree(); long degree = 0; for (Pair pair : parse(types)) { - degree += getDegreeSafe(node, pair.first(), pair.other()); + degree += getDegreeSafe(node, pair.getLeft(), pair.getRight()); } return degree; } @@ -577,8 +577,8 @@ public List relationshipTypes(@Name("node") Node node, @Name(value = "ty if (types == null || types.isEmpty()) return relTypes; List result = new ArrayList<>(relTypes.size()); for (Pair p : parse(types)) { - String name = p.first().name(); - if (relTypes.contains(name) && node.hasRelationship(p.other(),p.first())) { + String name = p.getLeft().name(); + if (relTypes.contains(name) && node.hasRelationship(p.getRight(),p.getLeft())) { result.add(name); } } @@ -611,8 +611,8 @@ public Map relationshipExists(@Name("node") Node node, @Name(val List relTypes = Iterables.stream(node.getRelationshipTypes()).map(RelationshipType::name).toList(); Map result = new HashMap<>(); for (Pair p : parse(types)) { - String name = p.first().name(); - boolean hasRelationship = relTypes.contains(name) && node.hasRelationship(p.other(), p.first()); + String name = p.getLeft().name(); + boolean hasRelationship = relTypes.contains(name) && node.hasRelationship(p.getRight(), p.getLeft()); result.put(format(p), hasRelationship); } return result; diff --git a/core/src/main/java/apoc/path/RelationshipSequenceExpander.java b/core/src/main/java/apoc/path/RelationshipSequenceExpander.java index 528c1c0c8..0071615a1 100644 --- a/core/src/main/java/apoc/path/RelationshipSequenceExpander.java +++ b/core/src/main/java/apoc/path/RelationshipSequenceExpander.java @@ -3,11 +3,11 @@ import apoc.util.collection.Iterables; import apoc.util.collection.Iterators; import apoc.util.collection.NestingResourceIterator; -import apoc.util.collection.Pair; import apoc.util.collection.ResourceClosingIterator; import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.tuple.Pair; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Path; @@ -93,8 +93,8 @@ public ResourceIterable expand( Path path, BranchState state ) { return Iterables.asResourceIterable(Iterators.asList(new NestingResourceIterator<>(stepRels.iterator()) { @Override protected ResourceIterator createNestedIterator( Pair entry ) { - RelationshipType type = entry.first(); - Direction dir = entry.other(); + RelationshipType type = entry.getLeft(); + Direction dir = entry.getRight(); ResourceIterable relationships1; if ( type == null ) diff --git a/core/src/main/java/apoc/periodic/Periodic.java b/core/src/main/java/apoc/periodic/Periodic.java index 3921ab84f..3984ce452 100644 --- a/core/src/main/java/apoc/periodic/Periodic.java +++ b/core/src/main/java/apoc/periodic/Periodic.java @@ -3,9 +3,9 @@ import apoc.Pools; import apoc.util.collection.Iterables; import apoc.util.collection.Iterators; -import apoc.util.collection.Pair; import apoc.util.Util; import apoc.periodic.PeriodicUtils.JobInfo; +import org.apache.commons.lang3.tuple.Pair; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Result; import org.neo4j.graphdb.Transaction; @@ -263,8 +263,8 @@ public Stream iterate( try (Result result = tx.execute(slottedRuntime(cypherIterate),params)) { Pair prepared = PeriodicUtils.prepareInnerStatement(cypherAction, batchMode, result.columns(), "_batch"); - String innerStatement = applyPlanner(prepared.first(), Planner.valueOf((String) config.getOrDefault("planner", Planner.DEFAULT.name()))); - boolean iterateList = prepared.other(); + String innerStatement = applyPlanner(prepared.getLeft(), Planner.valueOf((String) config.getOrDefault("planner", Planner.DEFAULT.name()))); + boolean iterateList = prepared.getRight(); String periodicId = UUID.randomUUID().toString(); if (log.isDebugEnabled()) { log.debug("Starting periodic iterate from `%s` operation using iteration `%s` in separate thread with id: `%s`", cypherIterate,cypherAction, periodicId); diff --git a/core/src/main/java/apoc/refactor/util/RefactorUtil.java b/core/src/main/java/apoc/refactor/util/RefactorUtil.java index 10dc91bee..92036228f 100644 --- a/core/src/main/java/apoc/refactor/util/RefactorUtil.java +++ b/core/src/main/java/apoc/refactor/util/RefactorUtil.java @@ -1,6 +1,6 @@ package apoc.refactor.util; -import apoc.util.collection.Pair; +import org.apache.commons.lang3.tuple.Pair; import org.neo4j.graphdb.*; import java.util.List; diff --git a/core/src/main/java/apoc/stats/DegreeDistribution.java b/core/src/main/java/apoc/stats/DegreeDistribution.java index 39f557fa2..fb6d7558e 100644 --- a/core/src/main/java/apoc/stats/DegreeDistribution.java +++ b/core/src/main/java/apoc/stats/DegreeDistribution.java @@ -2,9 +2,9 @@ import apoc.Pools; import apoc.path.RelationshipTypeAndDirections; -import apoc.util.collection.Pair; import apoc.util.kernel.MultiThreadedGlobalGraphOperations; import org.HdrHistogram.AtomicHistogram; +import org.apache.commons.lang3.tuple.Pair; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.RelationshipType; import org.neo4j.internal.kernel.api.CursorFactory; @@ -119,10 +119,10 @@ public List prepareStats(String types) { } List> pairs = RelationshipTypeAndDirections.parse(types); for (Pair pair : pairs) { - String typeName = pair.first() == null ? null : pair.first().name(); + String typeName = pair.getLeft() == null ? null : pair.getLeft().name(); int type = typeName == null ? ANY_RELATIONSHIP_TYPE : tokenRead.relationshipType(typeName); long total = read.countsForRelationship(ANY_LABEL, type, ANY_LABEL); - stats.add(new DegreeStats(typeName, type, pair.other(), total)); + stats.add(new DegreeStats(typeName, type, pair.getRight(), total)); } return stats; } diff --git a/core/src/main/java/apoc/text/Strings.java b/core/src/main/java/apoc/text/Strings.java index 26815ce4b..d1386829f 100644 --- a/core/src/main/java/apoc/text/Strings.java +++ b/core/src/main/java/apoc/text/Strings.java @@ -1,8 +1,8 @@ package apoc.text; -import apoc.util.collection.Pair; import apoc.util.Util; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.text.similarity.HammingDistance; import org.apache.commons.text.similarity.JaroWinklerDistance; import org.apache.commons.text.similarity.LevenshteinDistance; @@ -576,9 +576,9 @@ public String toCypher(@Name("value") Object value, @Name(value = "config",defau } return '{'+values.entrySet().stream() .map((e)-> Pair.of(e.getKey(), toCypher(e.getValue(),config))) - .filter((p)->p.other() != null) - .sorted(Comparator.comparing(Pair::first)) - .map((p) -> quote(p.first())+":"+p.other()) + .filter((p)->p.getRight() != null) + .sorted(Comparator.comparing(Pair::getLeft)) + .map((p) -> quote(p.getLeft())+":"+p.getRight()) .collect(Collectors.joining(","))+'}'; } return null; diff --git a/core/src/test/java/apoc/load/LoadCoreSecurityTest.java b/core/src/test/java/apoc/load/LoadCoreSecurityTest.java index 15b034c4e..5090eb39b 100644 --- a/core/src/test/java/apoc/load/LoadCoreSecurityTest.java +++ b/core/src/test/java/apoc/load/LoadCoreSecurityTest.java @@ -108,7 +108,7 @@ public void testIllegalFSAccessWithImportDisabled() { @Test public void testIllegalFSAccessWithImportEnabled() { final String message = apocProcedure + " should throw an exception"; - final String fileName = SensitivePathGenerator.etcPasswd(db).first(); + final String fileName = SensitivePathGenerator.etcPasswd(db).getLeft(); ApocConfig.apocConfig().setProperty(ApocConfig.APOC_IMPORT_FILE_ENABLED, true); ApocConfig.apocConfig().setProperty(ApocConfig.APOC_IMPORT_FILE_USE_NEO4J_CONFIG, true); ApocConfig.apocConfig().setProperty(ApocConfig.APOC_IMPORT_FILE_ALLOW__READ__FROM__FILESYSTEM, false); @@ -126,7 +126,7 @@ public void testIllegalFSAccessWithImportEnabled() { public void testReadSensitiveFileWorks() { // as we're defining ApocConfig.APOC_IMPORT_FILE_ALLOW__READ__FROM__FILESYSTEM to true // and ApocConfig.APOC_IMPORT_FILE_ALLOW__READ__FROM__FILESYSTEM to false the next call should work - final String fileName = SensitivePathGenerator.etcPasswd(db).first(); + final String fileName = SensitivePathGenerator.etcPasswd(db).getLeft(); ApocConfig.apocConfig().setProperty(ApocConfig.APOC_IMPORT_FILE_ENABLED, true); ApocConfig.apocConfig().setProperty(ApocConfig.APOC_IMPORT_FILE_USE_NEO4J_CONFIG, false); ApocConfig.apocConfig().setProperty(ApocConfig.APOC_IMPORT_FILE_ALLOW__READ__FROM__FILESYSTEM, true); diff --git a/core/src/test/java/apoc/periodic/PeriodicUtilsTest.java b/core/src/test/java/apoc/periodic/PeriodicUtilsTest.java index 5550acf9a..4403648f9 100644 --- a/core/src/test/java/apoc/periodic/PeriodicUtilsTest.java +++ b/core/src/test/java/apoc/periodic/PeriodicUtilsTest.java @@ -1,6 +1,6 @@ package apoc.periodic; -import apoc.util.collection.Pair; +import org.apache.commons.lang3.tuple.Pair; import org.junit.Test; import java.util.List; @@ -15,56 +15,56 @@ public class PeriodicUtilsTest { public void iterateListPrefixActionStatementWithUnwind() { BatchMode batchMode = BatchMode.fromIterateList(true); Pair prepared = prepareInnerStatement("SET n:Actor", batchMode, List.of("n"), "_batch"); - assertTrue(prepared.other()); - assertEquals("UNWIND $_batch AS _batch WITH _batch.n AS n SET n:Actor", prepared.first()); + assertTrue(prepared.getRight()); + assertEquals("UNWIND $_batch AS _batch WITH _batch.n AS n SET n:Actor", prepared.getLeft()); } @Test public void dontUnwindAnUnwindOfThe$_batchParameter() { BatchMode batchMode = BatchMode.fromIterateList(true); Pair prepared = prepareInnerStatement("UNWIND $_batch AS p SET p:Actor", batchMode, List.of("p"), "_batch"); - assertTrue(prepared.other()); - assertEquals("UNWIND $_batch AS p SET p:Actor", prepared.first()); + assertTrue(prepared.getRight()); + assertEquals("UNWIND $_batch AS p SET p:Actor", prepared.getLeft()); } @Test public void dontUnwindAWithOfColumnNames() { BatchMode batchMode = BatchMode.fromIterateList(true); Pair prepared = prepareInnerStatement("WITH $p as p SET p.lastname=p.name REMOVE p.name", batchMode, List.of("p"), "_batch"); - assertFalse(prepared.other()); - assertEquals("WITH $p as p SET p.lastname=p.name REMOVE p.name", prepared.first()); + assertFalse(prepared.getRight()); + assertEquals("WITH $p as p SET p.lastname=p.name REMOVE p.name", prepared.getLeft()); } @Test public void noIterateListNoPrefixOnActionStatement() { BatchMode batchMode = BatchMode.fromIterateList(false); Pair prepared = prepareInnerStatement("SET n:Actor", batchMode, List.of("n"), "_batch"); - assertFalse(prepared.other()); - assertEquals(" WITH $n AS n SET n:Actor", prepared.first()); + assertFalse(prepared.getRight()); + assertEquals(" WITH $n AS n SET n:Actor", prepared.getLeft()); } @Test public void noIterateListNoPrefixOnMultipleActionStatement() { BatchMode batchMode = BatchMode.fromIterateList(false); Pair prepared = prepareInnerStatement("SET n:Actor, p:Person", batchMode, List.of("n", "p"), "_batch"); - assertFalse(prepared.other()); - assertEquals(" WITH $n AS n,$p AS p SET n:Actor, p:Person", prepared.first()); + assertFalse(prepared.getRight()); + assertEquals(" WITH $n AS n,$p AS p SET n:Actor, p:Person", prepared.getLeft()); } @Test public void dontAddAnExtraWithIfParametersNamedAfterColumnsExistInStatement() { BatchMode batchMode = BatchMode.fromIterateList(false); Pair prepared = prepareInnerStatement("WITH $n AS x SET x:Actor", batchMode, List.of("n"), "_batch"); - assertFalse(prepared.other()); - assertEquals("WITH $n AS x SET x:Actor", prepared.first()); + assertFalse(prepared.getRight()); + assertEquals("WITH $n AS x SET x:Actor", prepared.getLeft()); } @Test public void passThrough$_batchWithNoUnwind() { BatchMode batchMode = BatchMode.BATCH_SINGLE; Pair prepared = prepareInnerStatement("UNWIND $_batch AS batch WITH batch.x AS x SET x:Actor", batchMode, List.of("x"), "_batch"); - assertTrue(prepared.other()); - assertEquals("UNWIND $_batch AS batch WITH batch.x AS x SET x:Actor", prepared.first()); + assertTrue(prepared.getRight()); + assertEquals("UNWIND $_batch AS batch WITH batch.x AS x SET x:Actor", prepared.getLeft()); } } \ No newline at end of file diff --git a/core/src/test/java/apoc/util/UtilTest.java b/core/src/test/java/apoc/util/UtilTest.java index 16e6d0901..a09f49590 100644 --- a/core/src/test/java/apoc/util/UtilTest.java +++ b/core/src/test/java/apoc/util/UtilTest.java @@ -1,6 +1,6 @@ package apoc.util; -import apoc.util.collection.Pair; +import org.apache.commons.lang3.tuple.Pair; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; diff --git a/test-utils/src/main/java/apoc/util/SensitivePathGenerator.java b/test-utils/src/main/java/apoc/util/SensitivePathGenerator.java index d3aa4196e..46fa1f268 100644 --- a/test-utils/src/main/java/apoc/util/SensitivePathGenerator.java +++ b/test-utils/src/main/java/apoc/util/SensitivePathGenerator.java @@ -1,6 +1,6 @@ package apoc.util; -import apoc.util.collection.Pair; +import org.apache.commons.lang3.tuple.Pair; import org.neo4j.kernel.internal.GraphDatabaseAPI; import java.nio.file.Path; From 61ef528bf98a6b8ebee5826bd57c9eb6a3271a12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louise=20S=C3=B6derstr=C3=B6m?= Date: Fri, 30 Sep 2022 11:36:19 +0200 Subject: [PATCH 8/9] Add tests for helper methods from Neo4j --- common/build.gradle | 1 + .../AbstractResourceIterableTest.java | 320 ++++++++++++++++++ .../util/collection/CollectionTestHelper.java | 67 ++++ .../apoc/util/collection/IterablesTest.java | 93 +++++ .../ResourceClosingIteratorTest.java | 38 +++ 5 files changed, 519 insertions(+) create mode 100644 common/src/test/java/apoc/util/collection/AbstractResourceIterableTest.java create mode 100644 common/src/test/java/apoc/util/collection/CollectionTestHelper.java create mode 100644 common/src/test/java/apoc/util/collection/IterablesTest.java create mode 100644 common/src/test/java/apoc/util/collection/ResourceClosingIteratorTest.java diff --git a/common/build.gradle b/common/build.gradle index 1fb575bc1..e23f034a8 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -84,6 +84,7 @@ dependencies { testImplementation group: 'org.neo4j', name: 'neo4j-kernel', version: neo4jVersionEffective, classifier: "tests" testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.13.2' testImplementation group: 'org.mockito', name: 'mockito-core', version: '4.2.0' + testImplementation group: 'pl.pragmatists', name: 'JUnitParams', version: '1.1.1' configurations.all { exclude group: 'org.slf4j', module: 'slf4j-nop' diff --git a/common/src/test/java/apoc/util/collection/AbstractResourceIterableTest.java b/common/src/test/java/apoc/util/collection/AbstractResourceIterableTest.java new file mode 100644 index 000000000..767950aa1 --- /dev/null +++ b/common/src/test/java/apoc/util/collection/AbstractResourceIterableTest.java @@ -0,0 +1,320 @@ +package apoc.util.collection; + +import static apoc.util.collection.CollectionTestHelper.asIterator; +import static apoc.util.collection.CollectionTestHelper.emptyResourceIterator; +import static apoc.util.collection.CollectionTestHelper.resourceIterator; +import static apoc.util.collection.ResourceClosingIterator.newResourceIterator; +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Stream; +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; +import org.apache.commons.lang3.mutable.MutableBoolean; +import org.apache.commons.lang3.mutable.MutableInt; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.neo4j.graphdb.Resource; +import org.neo4j.graphdb.ResourceIterator; + +@RunWith(JUnitParamsRunner.class) +public class AbstractResourceIterableTest { + @Test + public void shouldDelegateToUnderlyingIterableForData() { + // Given + final var iterableClosed = new MutableBoolean(false); + final var iteratorClosed = new MutableBoolean(false); + + final var items = Arrays.asList(0, 1, 2); + + // When + final var iterable = new AbstractResourceIterable() { + @Override + protected ResourceIterator newIterator() { + return resourceIterator(items.iterator(), iteratorClosed::setTrue); + } + + @Override + protected void onClosed() { + iterableClosed.setTrue(); + } + }; + final var iterator = iterable.iterator(); + + // Then + assertThat( Iterators.asList(iterator)).containsExactlyElementsOf(items); + assertThat(iteratorClosed.isTrue()).isTrue(); + assertThat(iterableClosed.isTrue()).isFalse(); + } + + @Test + @Parameters({"0", "1", "2", "3", "10"}) + public void callToIteratorShouldCreateNewIterators(int numberOfIterators) { + // Given + final var iterableClosed = new MutableBoolean(false); + final var iteratorCount = new MutableInt(); + + // When + final var iterable = new AbstractResourceIterable() { + @Override + protected ResourceIterator newIterator() { + iteratorCount.increment(); + return resourceIterator( asIterator(0), Resource.EMPTY); + } + + @Override + protected void onClosed() { + iterableClosed.setTrue(); + } + }; + + final var iterators = new ArrayList>(); + for (int i = 0; i < numberOfIterators; i++) { + iterators.add(iterable.iterator()); + } + iterable.close(); + + // Then + assertThat(iterableClosed.isTrue()).isTrue(); + assertThat(iteratorCount.getValue()).isEqualTo(numberOfIterators); + assertThat(iterators).containsOnlyOnceElementsOf(new HashSet<>(iterators)); + } + + @Test + public void shouldCloseAllIteratorsIfCloseCalledOnIterable() { + // Given + final var iteratorsClosed = Arrays.asList(false, false, false, false); + + // When + final var iterable = new AbstractResourceIterable() { + private int created; + + @Override + protected ResourceIterator newIterator() { + var pos = created; + created++; + return resourceIterator( + asIterator(0), () -> iteratorsClosed.set(pos, true)); + } + }; + iterable.iterator(); + iterable.iterator(); + iterable.iterator(); + iterable.close(); + + // Then + assertThat(iteratorsClosed.get(0)).isTrue(); + assertThat(iteratorsClosed.get(1)).isTrue(); + assertThat(iteratorsClosed.get(2)).isTrue(); + assertThat(iteratorsClosed.get(3)).isFalse(); + } + + @Test + public void shouldCloseAllIteratorsEvenIfOnlySomeCloseCalled() { + // Given + final var iteratorsClosed = new MutableInt(); + + // When + final var iterable = new AbstractResourceIterable() { + @Override + protected ResourceIterator newIterator() { + return resourceIterator( asIterator(0), iteratorsClosed::increment); + } + }; + final var iterator1 = iterable.iterator(); + iterable.iterator(); + final var iterator2 = iterable.iterator(); + iterable.iterator(); + final var iterator3 = iterable.iterator(); + iterable.iterator(); + iterable.iterator(); + + // go out of order + iterator3.close(); + iterator1.close(); + iterator2.close(); + iterable.close(); + + // Then + assertThat(iteratorsClosed.getValue()).isEqualTo(7); + } + + @Test + public void failIteratorCreationAfterIterableClosed() { + // Given + final var iteratorCreated = new MutableBoolean(false); + + // When + final var iterable = new AbstractResourceIterable() { + @Override + protected ResourceIterator newIterator() { + iteratorCreated.setTrue(); + return emptyResourceIterator(); + } + }; + iterable.close(); + + // Then + assertThatThrownBy(iterable::iterator); + assertThat(iteratorCreated.isTrue()).isFalse(); + } + + @Test + public void shouldCloseIteratorIfCloseCalled() { + // Given + final var iterableClosed = new MutableBoolean(false); + final var iteratorCreated = new MutableBoolean(false); + final var iteratorClosed = new MutableBoolean(false); + + // When + final var iterable = new AbstractResourceIterable() { + @Override + protected ResourceIterator newIterator() { + iteratorCreated.setTrue(); + return resourceIterator(List.of(0).iterator(), iteratorClosed::setTrue); + } + + @Override + protected void onClosed() { + iterableClosed.setTrue(); + } + }; + assertThat(iterable.iterator().hasNext()).isTrue(); + iterable.close(); + + // Then + assertThat(iteratorCreated.isTrue()).isTrue(); + assertThat(iteratorClosed.isTrue()).isTrue(); + assertThat(iterableClosed.isTrue()).isTrue(); + } + + @Test + public void shouldCloseIteratorOnForEachFailure() { + // Given + final var iterableClosed = new MutableBoolean(false); + final var iteratorClosed = new MutableBoolean(false); + + @SuppressWarnings("unchecked") + final var intIterator = (Iterator) mock(Iterator.class); + when(intIterator.hasNext()).thenReturn(true).thenReturn(true); + when(intIterator.next()).thenReturn(1).thenThrow(IllegalStateException.class); + + // When + final var iterable = new AbstractResourceIterable() { + @Override + protected ResourceIterator newIterator() { + return resourceIterator(intIterator, iteratorClosed::setTrue); + } + + @Override + protected void onClosed() { + iterableClosed.setTrue(); + } + }; + + // Then + final var emitted = new ArrayList(); + assertThatThrownBy(() -> { + try (iterable) { + for (var item : iterable) { + emitted.add(item); + } + } + }); + assertThat(emitted).isEqualTo(List.of(1)); + assertThat(iteratorClosed.isTrue()).isTrue(); + assertThat(iterableClosed.isTrue()).isTrue(); + } + + @Test + public void shouldCloseIteratorOnForEachCompletion() { + // Given + final var iterableClosed = new MutableBoolean(false); + final var iteratorClosed = new MutableBoolean(false); + + final var items = Arrays.asList(0, 1, 2); + + // When + final var iterable = new AbstractResourceIterable() { + @Override + protected ResourceIterator newIterator() { + return resourceIterator(items.iterator(), iteratorClosed::setTrue); + } + + @Override + protected void onClosed() { + iterableClosed.setTrue(); + } + }; + + final var emitted = new ArrayList(); + for (var item : iterable) { + emitted.add(item); + } + + // Then + assertThat(emitted).isEqualTo(items); + assertThat(iteratorClosed.isTrue()).isTrue(); + assertThat(iterableClosed.isTrue()).isFalse(); + } + + @Test + public void streamShouldCloseIteratorAndIterable() { + // Given + final var iterableClosed = new MutableBoolean(false); + final var iteratorClosed = new MutableBoolean(false); + final var resourceIterator = newResourceIterator(asIterator(1, 2, 3), iteratorClosed::setTrue); + + final var iterable = new AbstractResourceIterable() { + @Override + protected ResourceIterator newIterator() { + return resourceIterator; + } + + @Override + protected void onClosed() { + iterableClosed.setTrue(); + } + }; + + // When + try (Stream stream = iterable.stream()) { + final var result = stream.toList(); + assertThat(result).isEqualTo(asList(1, 2, 3)); + } + + // Then + assertThat(iterableClosed.isTrue()).isTrue(); + assertThat(iteratorClosed.isTrue()).isTrue(); + } + + @Test + public void streamShouldCloseMultipleOnCompleted() { + // Given + final var closed = new MutableInt(); + Resource resource = closed::incrementAndGet; + final var resourceIterator = newResourceIterator(asIterator(1, 2, 3), resource, resource); + + final var iterable = new AbstractResourceIterable() { + @Override + protected ResourceIterator newIterator() { + return resourceIterator; + } + }; + + // When + final var result = iterable.stream().toList(); + + // Then + assertThat(result).isEqualTo(asList(1, 2, 3)); + assertThat(closed.intValue()).isEqualTo(2); + } +} diff --git a/common/src/test/java/apoc/util/collection/CollectionTestHelper.java b/common/src/test/java/apoc/util/collection/CollectionTestHelper.java new file mode 100644 index 000000000..962023d90 --- /dev/null +++ b/common/src/test/java/apoc/util/collection/CollectionTestHelper.java @@ -0,0 +1,67 @@ +package apoc.util.collection; + +import java.util.Iterator; +import java.util.NoSuchElementException; +import org.neo4j.graphdb.Resource; +import org.neo4j.graphdb.ResourceIterator; + +/** + * Methods from Neo4js Iterators.java which are only needed in tests in APOC + */ +public class CollectionTestHelper +{ + public static ResourceIterator resourceIterator(final Iterator iterator, final Resource resource) { + return new PrefetchingResourceIterator<>() { + @Override + public void close() { + resource.close(); + } + + @Override + protected T fetchNextOrNull() { + return iterator.hasNext() ? iterator.next() : null; + } + }; + } + @SuppressWarnings("unchecked") + public static ResourceIterator emptyResourceIterator() { + return (ResourceIterator) EmptyResourceIterator.EMPTY_RESOURCE_ITERATOR; + } + + private static class EmptyResourceIterator implements ResourceIterator { + private static final ResourceIterator EMPTY_RESOURCE_ITERATOR = new EmptyResourceIterator<>(); + + @Override + public void close() {} + + @Override + public boolean hasNext() { + return false; + } + + @Override + public E next() { + throw new NoSuchElementException(); + } + } + + public static Iterator asIterator(final int... array) { + return new Iterator<>() { + private int index; + + @Override + public boolean hasNext() { + return index < array.length; + } + + @Override + public Integer next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + + return array[index++]; + } + }; + } +} diff --git a/common/src/test/java/apoc/util/collection/IterablesTest.java b/common/src/test/java/apoc/util/collection/IterablesTest.java new file mode 100644 index 000000000..615315bfb --- /dev/null +++ b/common/src/test/java/apoc/util/collection/IterablesTest.java @@ -0,0 +1,93 @@ +package apoc.util.collection; + +import static apoc.util.collection.CollectionTestHelper.emptyResourceIterator; +import static apoc.util.collection.ResourceClosingIterator.newResourceIterator; +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.apache.commons.lang3.mutable.MutableBoolean; +import org.junit.Test; +import org.neo4j.graphdb.ResourceIterator; + +public class IterablesTest { + + @Test + public void count() { + // Given + final var subjects = asList(1, 2, 3, 4, 5); + final var iteratorClosed = new MutableBoolean(false); + final var iterableClosed = new MutableBoolean(false); + final var iterable = new AbstractResourceIterable() { + @Override + protected ResourceIterator newIterator() { + return newResourceIterator(subjects.iterator(), iteratorClosed::setTrue); + } + + @Override + protected void onClosed() { + iterableClosed.setTrue(); + } + }; + + // when + long count = Iterables.count(iterable); + + // then + assertThat(count).isEqualTo(subjects.size()); + assertThat(iteratorClosed.isTrue()).isTrue(); + assertThat(iterableClosed.isTrue()).isTrue(); + } + + @Test + public void firstNoItems() { + // Given + final var iteratorClosed = new MutableBoolean(false); + final var iterableClosed = new MutableBoolean(false); + final var iterable = new AbstractResourceIterable() { + @Override + protected ResourceIterator newIterator() { + return newResourceIterator( emptyResourceIterator(), iteratorClosed::setTrue); + } + + @Override + protected void onClosed() { + iterableClosed.setTrue(); + } + }; + + // when + assertThatThrownBy(() -> Iterables.first(iterable)); + + // then + assertThat(iteratorClosed.isTrue()).isTrue(); + assertThat(iterableClosed.isTrue()).isTrue(); + } + + @Test + public void firstWithItems() { + // Given + final var subjects = asList(1, 2, 3, 4, 5); + final var iteratorClosed = new MutableBoolean(false); + final var iterableClosed = new MutableBoolean(false); + final var iterable = new AbstractResourceIterable() { + @Override + protected ResourceIterator newIterator() { + return newResourceIterator(subjects.iterator(), iteratorClosed::setTrue); + } + + @Override + protected void onClosed() { + iterableClosed.setTrue(); + } + }; + + // when + long first = Iterables.first(iterable); + + // then + assertThat(first).isEqualTo(1); + assertThat(iteratorClosed.isTrue()).isTrue(); + assertThat(iterableClosed.isTrue()).isTrue(); + } +} diff --git a/common/src/test/java/apoc/util/collection/ResourceClosingIteratorTest.java b/common/src/test/java/apoc/util/collection/ResourceClosingIteratorTest.java new file mode 100644 index 000000000..4e0feedff --- /dev/null +++ b/common/src/test/java/apoc/util/collection/ResourceClosingIteratorTest.java @@ -0,0 +1,38 @@ +package apoc.util.collection; + +import static apoc.util.collection.CollectionTestHelper.resourceIterator; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import org.apache.commons.lang3.mutable.MutableBoolean; +import org.junit.Test; +import org.neo4j.graphdb.ResourceIterator; + +public class ResourceClosingIteratorTest { + @Test + public void fromResourceIterableShouldCloseParentIterable() { + final var iterableClosed = new MutableBoolean(false); + final var iteratorClosed = new MutableBoolean(false); + + final var items = Arrays.asList(0, 1, 2); + + // When + final var iterable = new AbstractResourceIterable() { + @Override + protected ResourceIterator newIterator() { + return resourceIterator(items.iterator(), iteratorClosed::setTrue); + } + + @Override + protected void onClosed() { + iterableClosed.setTrue(); + } + }; + ResourceIterator iterator = ResourceClosingIterator.fromResourceIterable(iterable); + + // Then + assertThat( Iterators.asList(iterator)).containsExactlyElementsOf(items); + assertThat(iteratorClosed.isTrue()).isTrue(); + assertThat(iterableClosed.isTrue()).isTrue(); + } +} From 322240de4810a376e4619d6a936044579fe676ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louise=20S=C3=B6derstr=C3=B6m?= Date: Wed, 5 Oct 2022 10:17:32 +0200 Subject: [PATCH 9/9] Simplify test assertions --- .../AbstractResourceIterableTest.java | 28 ++++++++++--------- .../apoc/util/collection/IterablesTest.java | 13 +++++---- .../ResourceClosingIteratorTest.java | 7 +++-- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/common/src/test/java/apoc/util/collection/AbstractResourceIterableTest.java b/common/src/test/java/apoc/util/collection/AbstractResourceIterableTest.java index 767950aa1..1d7606637 100644 --- a/common/src/test/java/apoc/util/collection/AbstractResourceIterableTest.java +++ b/common/src/test/java/apoc/util/collection/AbstractResourceIterableTest.java @@ -7,6 +7,8 @@ import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -51,8 +53,8 @@ protected void onClosed() { // Then assertThat( Iterators.asList(iterator)).containsExactlyElementsOf(items); - assertThat(iteratorClosed.isTrue()).isTrue(); - assertThat(iterableClosed.isTrue()).isFalse(); + assertTrue(iteratorClosed.booleanValue()); + assertFalse(iterableClosed.booleanValue()); } @Test @@ -83,7 +85,7 @@ protected void onClosed() { iterable.close(); // Then - assertThat(iterableClosed.isTrue()).isTrue(); + assertTrue(iterableClosed.booleanValue()); assertThat(iteratorCount.getValue()).isEqualTo(numberOfIterators); assertThat(iterators).containsOnlyOnceElementsOf(new HashSet<>(iterators)); } @@ -164,7 +166,7 @@ protected ResourceIterator newIterator() { // Then assertThatThrownBy(iterable::iterator); - assertThat(iteratorCreated.isTrue()).isFalse(); + assertFalse(iteratorCreated.booleanValue()); } @Test @@ -191,9 +193,9 @@ protected void onClosed() { iterable.close(); // Then - assertThat(iteratorCreated.isTrue()).isTrue(); - assertThat(iteratorClosed.isTrue()).isTrue(); - assertThat(iterableClosed.isTrue()).isTrue(); + assertTrue(iteratorCreated.booleanValue()); + assertTrue(iteratorClosed.booleanValue()); + assertTrue(iterableClosed.booleanValue()); } @Test @@ -230,8 +232,8 @@ protected void onClosed() { } }); assertThat(emitted).isEqualTo(List.of(1)); - assertThat(iteratorClosed.isTrue()).isTrue(); - assertThat(iterableClosed.isTrue()).isTrue(); + assertTrue(iteratorClosed.booleanValue()); + assertTrue(iterableClosed.booleanValue()); } @Test @@ -262,8 +264,8 @@ protected void onClosed() { // Then assertThat(emitted).isEqualTo(items); - assertThat(iteratorClosed.isTrue()).isTrue(); - assertThat(iterableClosed.isTrue()).isFalse(); + assertTrue(iteratorClosed.booleanValue()); + assertFalse(iterableClosed.booleanValue()); } @Test @@ -292,8 +294,8 @@ protected void onClosed() { } // Then - assertThat(iterableClosed.isTrue()).isTrue(); - assertThat(iteratorClosed.isTrue()).isTrue(); + assertTrue(iterableClosed.booleanValue()); + assertTrue(iteratorClosed.booleanValue()); } @Test diff --git a/common/src/test/java/apoc/util/collection/IterablesTest.java b/common/src/test/java/apoc/util/collection/IterablesTest.java index 615315bfb..5dbc01fd8 100644 --- a/common/src/test/java/apoc/util/collection/IterablesTest.java +++ b/common/src/test/java/apoc/util/collection/IterablesTest.java @@ -5,6 +5,7 @@ import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertTrue; import org.apache.commons.lang3.mutable.MutableBoolean; import org.junit.Test; @@ -35,8 +36,8 @@ protected void onClosed() { // then assertThat(count).isEqualTo(subjects.size()); - assertThat(iteratorClosed.isTrue()).isTrue(); - assertThat(iterableClosed.isTrue()).isTrue(); + assertTrue(iteratorClosed.booleanValue()); + assertTrue(iterableClosed.booleanValue()); } @Test @@ -60,8 +61,8 @@ protected void onClosed() { assertThatThrownBy(() -> Iterables.first(iterable)); // then - assertThat(iteratorClosed.isTrue()).isTrue(); - assertThat(iterableClosed.isTrue()).isTrue(); + assertTrue(iteratorClosed.booleanValue()); + assertTrue(iterableClosed.booleanValue()); } @Test @@ -87,7 +88,7 @@ protected void onClosed() { // then assertThat(first).isEqualTo(1); - assertThat(iteratorClosed.isTrue()).isTrue(); - assertThat(iterableClosed.isTrue()).isTrue(); + assertTrue(iteratorClosed.booleanValue()); + assertTrue(iterableClosed.booleanValue()); } } diff --git a/common/src/test/java/apoc/util/collection/ResourceClosingIteratorTest.java b/common/src/test/java/apoc/util/collection/ResourceClosingIteratorTest.java index 4e0feedff..9c7cf7067 100644 --- a/common/src/test/java/apoc/util/collection/ResourceClosingIteratorTest.java +++ b/common/src/test/java/apoc/util/collection/ResourceClosingIteratorTest.java @@ -2,6 +2,7 @@ import static apoc.util.collection.CollectionTestHelper.resourceIterator; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; import java.util.Arrays; import org.apache.commons.lang3.mutable.MutableBoolean; @@ -31,8 +32,8 @@ protected void onClosed() { ResourceIterator iterator = ResourceClosingIterator.fromResourceIterable(iterable); // Then - assertThat( Iterators.asList(iterator)).containsExactlyElementsOf(items); - assertThat(iteratorClosed.isTrue()).isTrue(); - assertThat(iterableClosed.isTrue()).isTrue(); + assertThat(Iterators.asList(iterator)).containsExactlyElementsOf(items); + assertTrue(iteratorClosed.booleanValue()); + assertTrue(iterableClosed.booleanValue()); } }