From b7eb32682a3c4665d83c38c46125f442b80a3ec0 Mon Sep 17 00:00:00 2001 From: vga91 Date: Tue, 25 Jun 2024 09:28:32 +0200 Subject: [PATCH] Fixes #4108: Remove org.apache.commons.collections* imports --- .../ROOT/partials/xls-dependencies.adoc | 1 - extended/build.gradle | 29 ++++-- extended/src/main/java/apoc/agg/Rollup.java | 4 +- .../src/main/java/apoc/coll/CollExtended.java | 2 +- .../java/apoc/dv/VirtualizedResource.java | 9 +- .../apoc/export/xls/ExportXlsHandler.java | 4 +- .../apoc/util/ExtendedCollectionUtils.java | 96 +++++++++++++++++++ .../java/apoc/util/ExtendedListUtils.java | 26 +++++ .../main/java/apoc/util/ExtendedMapUtils.java | 14 +++ .../src/main/java/apoc/uuid/UuidHandler.java | 4 +- .../src/main/java/apoc/vectordb/ChromaDb.java | 2 +- .../src/main/java/apoc/vectordb/VectorDb.java | 4 +- extra-dependencies/xls/build.gradle | 1 - 13 files changed, 171 insertions(+), 25 deletions(-) create mode 100644 extended/src/main/java/apoc/util/ExtendedCollectionUtils.java create mode 100644 extended/src/main/java/apoc/util/ExtendedListUtils.java create mode 100644 extended/src/main/java/apoc/util/ExtendedMapUtils.java diff --git a/docs/asciidoc/modules/ROOT/partials/xls-dependencies.adoc b/docs/asciidoc/modules/ROOT/partials/xls-dependencies.adoc index 554cf51e1c..ca2b85ca3d 100644 --- a/docs/asciidoc/modules/ROOT/partials/xls-dependencies.adoc +++ b/docs/asciidoc/modules/ROOT/partials/xls-dependencies.adoc @@ -10,7 +10,6 @@ Alternatively, you can download these jars from Maven Repository (putting them i * https://repo1.maven.org/maven2/org/apache/poi/poi/5.1.0/poi-5.1.0.jar[poi-5.1.0.jar^] .Additional for XLSX files: -* https://repo1.maven.org/maven2/org/apache/commons/commons-collections4/4.4/commons-collections4-4.4.jar[commons-collections4-4.4.jar^] * https://repo1.maven.org/maven2/org/apache/poi/poi-ooxml/5.1.0/poi-ooxml-5.1.0.jar[poi-ooxml-5.1.0.jar^] * https://repo1.maven.org/maven2/org/apache/poi/poi-ooxml-lite/5.1.0/poi-ooxml-lite-5.1.0.jar[poi-ooxml-lite-5.1.0.jar^] * https://repo1.maven.org/maven2/org/apache/xmlbeans/xmlbeans/5.0.2/xmlbeans-5.0.2.jar[xmlbeans-5.0.2.jar^] diff --git a/extended/build.gradle b/extended/build.gradle index 65bb28fc86..48c90d3b6c 100644 --- a/extended/build.gradle +++ b/extended/build.gradle @@ -78,7 +78,6 @@ dependencies { implementation project(':common') implementation group: 'com.unboundid', name: 'unboundid-ldapsdk', version: '6.0.11' implementation group: 'org.jsoup', name: 'jsoup', version: '1.15.3' - implementation group: 'org.apache.commons', name: 'commons-collections4', version: '4.4' implementation group: 'org.apache.commons', name: 'commons-csv', version: '1.10.0', { exclude group: 'org.apache.commons', module: 'commons-io' exclude group: 'org.apache.commons', module: 'commons-lang3' @@ -92,8 +91,12 @@ dependencies { // same version as the one included in neo4j `lib` compileOnly group: 'org.neo4j.driver', name: 'neo4j-java-driver', version: '5.21.0' - compileOnly group: 'org.apache.poi', name: 'poi', version: '5.1.0' - compileOnly group: 'org.apache.poi', name: 'poi-ooxml', version: '5.1.0' + compileOnly group: 'org.apache.poi', name: 'poi', version: '5.1.0', { + exclude group: 'org.apache.commons', module: 'commons-collections4' + } + compileOnly group: 'org.apache.poi', name: 'poi-ooxml', version: '5.1.0', { + exclude group: 'org.apache.commons', module: 'commons-collections4' + } compileOnly group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.10.0', { exclude group: 'com.google.guava', module: 'guava' } @@ -124,8 +127,12 @@ dependencies { // These dependencies affect the tests only, they will not be packaged in the resulting .jar testImplementation project(':test-utils') testImplementation project(':core') - testImplementation group: 'org.apache.poi', name: 'poi', version: '5.1.0' - testImplementation group: 'org.apache.poi', name: 'poi-ooxml', version: '5.1.0' + testImplementation group: 'org.apache.poi', name: 'poi', version: '5.1.0', { + exclude group: 'org.apache.commons', module: 'commons-collections4' + } + testImplementation group: 'org.apache.poi', name: 'poi-ooxml', version: '5.1.0', { + exclude group: 'org.apache.commons', module: 'commons-collections4' + } testImplementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.10.0' testImplementation group: 'io.github.bonigarcia', name: 'webdrivermanager', version: '5.4.0' testImplementation group: 'com.github.stefanbirkner', name: 'system-rules', version: '1.19.0' @@ -134,8 +141,12 @@ dependencies { testImplementation group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: '1.6.0' testImplementation group: 'org.hamcrest', name: 'hamcrest-library', version: '1.3' testImplementation group: 'org.apache.derby', name: 'derby', version: '10.12.1.1' - testImplementation group: 'org.mock-server', name: 'mockserver-netty', version: '5.6.0' - testImplementation group: 'org.mock-server', name: 'mockserver-client-java', version: '5.6.0' + testImplementation group: 'org.mock-server', name: 'mockserver-netty', version: '5.6.0', { + exclude group: 'org.apache.commons', module: 'commons-collections4' + } + testImplementation group: 'org.mock-server', name: 'mockserver-client-java', version: '5.6.0', { + exclude group: 'org.apache.commons', module: 'commons-collections4' + } testImplementation group: 'com.amazonaws', name: 'aws-java-sdk-comprehend', version: '1.12.353' , withoutJacksons testImplementation group: 'org.xmlunit', name: 'xmlunit-core', version: '2.2.1' testImplementation group: 'com.github.adejanovski', name: 'cassandra-jdbc-wrapper', version: '3.1.0' @@ -144,7 +155,9 @@ dependencies { testImplementation group: 'org.zapodot', name: 'embedded-ldap-junit', version: '0.9.0' testImplementation group: 'org.mockito', name: 'mockito-core', version: '5.4.0' testImplementation group: 'org.apache.parquet', name: 'parquet-hadoop', version: '1.13.1', withoutServers - testImplementation group: 'com.opencsv', name: 'opencsv', version: '5.7.1' + testImplementation group: 'com.opencsv', name: 'opencsv', version: '5.7.1', { + exclude group: 'org.apache.commons', module: 'commons-collections4' + } configurations.all { exclude group: 'org.slf4j', module: 'slf4j-nop' diff --git a/extended/src/main/java/apoc/agg/Rollup.java b/extended/src/main/java/apoc/agg/Rollup.java index 63d4d0ff57..4a869861fe 100644 --- a/extended/src/main/java/apoc/agg/Rollup.java +++ b/extended/src/main/java/apoc/agg/Rollup.java @@ -1,8 +1,8 @@ package apoc.agg; import apoc.Extended; +import apoc.util.ExtendedListUtils; import apoc.util.Util; -import org.apache.commons.collections4.ListUtils; import org.neo4j.graphdb.Entity; import org.neo4j.procedure.Description; import org.neo4j.procedure.Name; @@ -106,7 +106,7 @@ public void aggregate( for (int i = 0; i <= groupKey.size(); i++) { // add NULL_ROLLUP to remaining elements, // e.g. `[, `NULL_ROLLUP`, `NULL_ROLLUP`]` - List partialKey = ListUtils.union(groupKey.subList(0, i), Collections.nCopies(groupKey.size() - i, NULL_ROLLUP)); + List partialKey = ExtendedListUtils.union(groupKey.subList(0, i), Collections.nCopies(groupKey.size() - i, NULL_ROLLUP)); if (!rolledUpData.containsKey(partialKey)) { rolledUpData.put(partialKey, new HashMap<>()); } diff --git a/extended/src/main/java/apoc/coll/CollExtended.java b/extended/src/main/java/apoc/coll/CollExtended.java index 8ae0169090..71ba3c6d0d 100644 --- a/extended/src/main/java/apoc/coll/CollExtended.java +++ b/extended/src/main/java/apoc/coll/CollExtended.java @@ -1,7 +1,7 @@ package apoc.coll; import apoc.Extended; -import org.apache.commons.collections4.CollectionUtils; +import apoc.util.CollectionUtils; import org.neo4j.procedure.Description; import org.neo4j.procedure.Name; import org.neo4j.procedure.UserFunction; diff --git a/extended/src/main/java/apoc/dv/VirtualizedResource.java b/extended/src/main/java/apoc/dv/VirtualizedResource.java index 423333480a..85f3e12e15 100644 --- a/extended/src/main/java/apoc/dv/VirtualizedResource.java +++ b/extended/src/main/java/apoc/dv/VirtualizedResource.java @@ -1,7 +1,6 @@ package apoc.dv; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.collections4.MapUtils; +import apoc.util.ExtendedMapUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; @@ -70,11 +69,11 @@ private void validateQueryParams(Object queryParams) { throw new IllegalArgumentException("Query Params cannot be null"); } final int actualSize; - if (queryParams instanceof Collection) { - actualSize = CollectionUtils.size(queryParams); + if (queryParams instanceof Collection collection) { + actualSize = collection.size(); } else if (queryParams instanceof Map) { final Map parameterMap = (Map) queryParams; - actualSize = MapUtils.size(parameterMap); + actualSize = ExtendedMapUtils.size(parameterMap); Set setParams = params.stream() .collect(Collectors.toSet()); final Set actualParams = parameterMap.keySet().stream().map(p -> "$" + p).collect(Collectors.toSet()); diff --git a/extended/src/main/java/apoc/export/xls/ExportXlsHandler.java b/extended/src/main/java/apoc/export/xls/ExportXlsHandler.java index bda05d807e..1f8783eb52 100644 --- a/extended/src/main/java/apoc/export/xls/ExportXlsHandler.java +++ b/extended/src/main/java/apoc/export/xls/ExportXlsHandler.java @@ -4,7 +4,7 @@ import apoc.export.util.ExportConfig; import apoc.export.util.ProgressReporter; import apoc.result.ProgressInfo; -import org.apache.commons.collections4.ListUtils; +import apoc.util.ExtendedListUtils; import org.apache.commons.lang3.tuple.Triple; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; @@ -143,7 +143,7 @@ private static void dumpSubGraph(SubGraph subgraph, XlsExportConfig config, Prog List keys = triple.getRight(); Row row = sheet.getRow(0); int cellNum = 0; - for (String key: ListUtils.union(magicKeys,keys)) { + for (String key: ExtendedListUtils.union(magicKeys,keys)) { sheet.autoSizeColumn(cellNum); Cell cell = row.createCell(cellNum++); cell.setCellValue(key); diff --git a/extended/src/main/java/apoc/util/ExtendedCollectionUtils.java b/extended/src/main/java/apoc/util/ExtendedCollectionUtils.java new file mode 100644 index 0000000000..5246eaf87a --- /dev/null +++ b/extended/src/main/java/apoc/util/ExtendedCollectionUtils.java @@ -0,0 +1,96 @@ +package apoc.util; + +import java.lang.reflect.Array; +import java.util.Collection; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Map; + +public class ExtendedCollectionUtils { + + /** + * NOTE: equivalent to `org.apache.commons.collections4.CollectionUtils` homonym method + * + * Gets the size of the collection/iterator specified. + *

+ * This method can handles objects as follows + *

+ *
    + *
  • Collection - the collection size + *
  • Map - the map size + *
  • Array - the array size + *
  • Iterator - the number of elements remaining in the iterator + *
  • Enumeration - the number of elements remaining in the enumeration + *
+ * + * @param object the object to get the size of, may be null + * @return the size of the specified collection or 0 if the object was null + * @throws IllegalArgumentException thrown if object is not recognized + * @since 3.1 + */ + public static int size(final Object object) { + if (object == null) { + return 0; + } + int total = 0; + if (object instanceof Map) { + total = ((Map) object).size(); + } else if (object instanceof Collection) { + total = ((Collection) object).size(); + } else if (object instanceof Iterable) { + total = sizeIterable((Iterable) object); + } else if (object instanceof Object[]) { + total = ((Object[]) object).length; + } else if (object instanceof Iterator) { + total = sizeIterator((Iterator) object); + } else if (object instanceof Enumeration) { + final Enumeration it = (Enumeration) object; + while (it.hasMoreElements()) { + total++; + it.nextElement(); + } + } else { + try { + total = Array.getLength(object); + } catch (final IllegalArgumentException ex) { + throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName()); + } + } + return total; + } + + /** + * Returns the number of elements contained in the given iterator. + *

+ * A null or empty iterator returns {@code 0}. + * + * @param iterator the iterator to check, may be null + * @return the number of elements contained in the iterator + * @since 4.1 + */ + public static int sizeIterator(final Iterator iterator) { + int size = 0; + if (iterator != null) { + while (iterator.hasNext()) { + iterator.next(); + size++; + } + } + return size; + } + + /** + * Returns the number of elements contained in the given iterator. + *

+ * A null or empty iterator returns {@code 0}. + * + * @param iterable the iterable to check, may be null + * @return the number of elements contained in the iterable + */ + public static int sizeIterable(final Iterable iterable) { + if (iterable instanceof Collection) { + return ((Collection) iterable).size(); + } + return 0; + } +} diff --git a/extended/src/main/java/apoc/util/ExtendedListUtils.java b/extended/src/main/java/apoc/util/ExtendedListUtils.java new file mode 100644 index 0000000000..a2f479e718 --- /dev/null +++ b/extended/src/main/java/apoc/util/ExtendedListUtils.java @@ -0,0 +1,26 @@ +package apoc.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class ExtendedListUtils { + + /** + * Returns a new list containing the second list appended to the + * first list. The {@link List#addAll(Collection)} operation is + * used to append the two given lists into a new list. + * + * @param the element type + * @param list1 the first list + * @param list2 the second list + * @return a new list containing the union of those lists + * @throws NullPointerException if either list is null + */ + public static List union(final List list1, final List list2) { + final ArrayList result = new ArrayList<>(list1.size() + list2.size()); + result.addAll(list1); + result.addAll(list2); + return result; + } +} diff --git a/extended/src/main/java/apoc/util/ExtendedMapUtils.java b/extended/src/main/java/apoc/util/ExtendedMapUtils.java new file mode 100644 index 0000000000..c6b388b07d --- /dev/null +++ b/extended/src/main/java/apoc/util/ExtendedMapUtils.java @@ -0,0 +1,14 @@ +package apoc.util; + +import java.util.Map; + +public class ExtendedMapUtils { + + public static int size(final Map map) { + return map == null ? 0 : map.size(); + } + + public static boolean isEmpty(final Map map) { + return map == null || map.isEmpty(); + } +} diff --git a/extended/src/main/java/apoc/uuid/UuidHandler.java b/extended/src/main/java/apoc/uuid/UuidHandler.java index 8123b2a8e5..901f301f35 100644 --- a/extended/src/main/java/apoc/uuid/UuidHandler.java +++ b/extended/src/main/java/apoc/uuid/UuidHandler.java @@ -7,7 +7,7 @@ import apoc.Pools; import apoc.SystemPropertyKeys; import apoc.util.Util; -import org.apache.commons.collections4.IterableUtils; +import apoc.util.collection.Iterables; import org.apache.commons.lang3.tuple.Pair; import org.neo4j.dbms.api.DatabaseManagementService; import org.neo4j.graphdb.GraphDatabaseService; @@ -147,7 +147,7 @@ public Void beforeCommit(TransactionData txData, Transaction transaction, GraphD final String propertyName = config.getUuidProperty(); List nodes = config.isAddToSetLabels() ? StreamSupport.stream(txData.assignedLabels().spliterator(), false).map(LabelEntry::node).collect(Collectors.toList()) - : IterableUtils.toList(txData.createdNodes()); + : Iterables.asList(txData.createdNodes()); try { nodes.forEach(node -> { if (node.hasLabel(Label.label(label)) && !node.hasProperty(propertyName)) { diff --git a/extended/src/main/java/apoc/vectordb/ChromaDb.java b/extended/src/main/java/apoc/vectordb/ChromaDb.java index 23d8d1e996..f0c76b5504 100644 --- a/extended/src/main/java/apoc/vectordb/ChromaDb.java +++ b/extended/src/main/java/apoc/vectordb/ChromaDb.java @@ -4,7 +4,7 @@ import apoc.ml.RestAPIConfig; import apoc.result.ListResult; import apoc.result.MapResult; -import org.apache.commons.collections4.CollectionUtils; +import apoc.util.CollectionUtils; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.security.URLAccessChecker; diff --git a/extended/src/main/java/apoc/vectordb/VectorDb.java b/extended/src/main/java/apoc/vectordb/VectorDb.java index 6123e84966..f136f4c6ee 100644 --- a/extended/src/main/java/apoc/vectordb/VectorDb.java +++ b/extended/src/main/java/apoc/vectordb/VectorDb.java @@ -5,10 +5,10 @@ import apoc.SystemPropertyKeys; import apoc.ml.RestAPIConfig; import apoc.result.ObjectResult; +import apoc.util.ExtendedMapUtils; import apoc.util.JsonUtil; import apoc.util.SystemDbUtil; import apoc.util.Util; -import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.tuple.Pair; import org.neo4j.graphdb.Entity; import org.neo4j.graphdb.GraphDatabaseService; @@ -134,7 +134,7 @@ private static Entity handleMapping(Transaction tx, VectorMappingConfig mapping, if (mapping.getEntityKey() == null) { return null; } - if (MapUtils.isEmpty(metadata)) { + if (ExtendedMapUtils.isEmpty(metadata)) { throw new RuntimeException("To use mapping config, the metadata should not be empty. Make sure you execute `YIELD metadata` on the procedure"); } Map metaProps = new HashMap<>(metadata); diff --git a/extra-dependencies/xls/build.gradle b/extra-dependencies/xls/build.gradle index fd8eca33e3..6ce9f5e558 100644 --- a/extra-dependencies/xls/build.gradle +++ b/extra-dependencies/xls/build.gradle @@ -32,5 +32,4 @@ dependencies { exclude group: 'org.apache.logging.log4j' } implementation group: 'com.github.virtuald', name: 'curvesapi', version: '1.06' - implementation group: 'org.apache.commons', name: 'commons-collections4', version: '4.4' }