From c5c10e5847a47ae6af1b8928bc68b6fb82d6216f Mon Sep 17 00:00:00 2001 From: Tamas Cservenak Date: Sat, 27 Jan 2024 12:34:23 +0100 Subject: [PATCH 1/3] [MRESOLVER-483] Classpath generation bugfix Rework whole class to use Streams --- https://issues.apache.org/jira/browse/MRESOLVER-483 --- .../util/graph/visitor/NodeListGenerator.java | 53 +++------ .../graph/visitor/NodeListGeneratorTest.java | 106 ++++++++++++++++++ 2 files changed, 121 insertions(+), 38 deletions(-) diff --git a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/visitor/NodeListGenerator.java b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/visitor/NodeListGenerator.java index 44c25d062..faecbb1da 100644 --- a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/visitor/NodeListGenerator.java +++ b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/visitor/NodeListGenerator.java @@ -20,9 +20,10 @@ import java.io.File; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; +import java.util.Objects; import java.util.function.Consumer; +import java.util.stream.Collectors; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.graph.Dependency; @@ -116,51 +117,27 @@ static List getNodesWithDependencies(List nodes) } static List getDependencies(List nodes, boolean includeUnresolved) { - List dependencies = new ArrayList<>(nodes.size()); - for (DependencyNode node : getNodesWithDependencies(nodes)) { - Dependency dependency = node.getDependency(); - if (includeUnresolved || dependency.getArtifact().getFile() != null) { - dependencies.add(dependency); - } - } - return dependencies; + return getNodesWithDependencies(nodes).stream() + .filter(d -> includeUnresolved || d.getArtifact().getFile() != null) + .map(DependencyNode::getDependency) + .collect(toList()); } static List getArtifacts(List nodes, boolean includeUnresolved) { - List artifacts = new ArrayList<>(nodes.size()); - for (DependencyNode node : getNodesWithDependencies(nodes)) { - Artifact artifact = node.getDependency().getArtifact(); - if (includeUnresolved || artifact.getFile() != null) { - artifacts.add(artifact); - } - } - - return artifacts; + return getNodesWithDependencies(nodes).stream() + .map(DependencyNode::getArtifact) + .filter(artifact -> includeUnresolved || artifact.getFile() != null) + .collect(toList()); } static List getFiles(List nodes) { - List files = new ArrayList<>(nodes.size()); - for (DependencyNode node : getNodesWithDependencies(nodes)) { - File file = node.getDependency().getArtifact().getFile(); - if (file != null) { - files.add(file); - } - } - return files; + return getNodesWithDependencies(nodes).stream() + .map(d -> d.getDependency().getArtifact().getFile()) + .filter(Objects::nonNull) + .collect(toList()); } static String getClassPath(List nodes) { - StringBuilder buffer = new StringBuilder(1024); - for (Iterator it = getNodesWithDependencies(nodes).iterator(); it.hasNext(); ) { - DependencyNode node = it.next(); - Artifact artifact = node.getDependency().getArtifact(); - if (artifact.getFile() != null) { - buffer.append(artifact.getFile().getAbsolutePath()); - if (it.hasNext()) { - buffer.append(File.pathSeparatorChar); - } - } - } - return buffer.toString(); + return getFiles(nodes).stream().map(File::getAbsolutePath).collect(Collectors.joining(File.pathSeparator)); } } diff --git a/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/visitor/NodeListGeneratorTest.java b/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/visitor/NodeListGeneratorTest.java index a805968d7..ce30601a1 100644 --- a/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/visitor/NodeListGeneratorTest.java +++ b/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/visitor/NodeListGeneratorTest.java @@ -18,9 +18,16 @@ */ package org.eclipse.aether.util.graph.visitor; +import java.io.File; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.graph.DependencyVisitor; import org.eclipse.aether.internal.test.util.DependencyGraphParser; import org.junit.jupiter.api.Test; @@ -107,4 +114,103 @@ void testLevelOrderDuplicateSuppression() throws Exception { assertSequence(nodeListGenerator.getNodes(), "a", "b", "d", "c", "e"); } + + @Test + void testEmptyResolvedClassPath() throws Exception { + DependencyNode root = parse("simple.txt"); + + NodeListGenerator nodeListGenerator = new NodeListGenerator(); + LevelOrderDependencyNodeConsumerVisitor visitor = + new LevelOrderDependencyNodeConsumerVisitor(nodeListGenerator); + root.accept(visitor); + + assertEquals(5, nodeListGenerator.getNodes().size()); + assertEquals(0, nodeListGenerator.getDependencies(false).size()); + assertEquals(5, nodeListGenerator.getDependencies(true).size()); + assertEquals(0, nodeListGenerator.getArtifacts(false).size()); + assertEquals(5, nodeListGenerator.getArtifacts(true).size()); + assertEquals(0, nodeListGenerator.getFiles().size()); + assertEquals("", nodeListGenerator.getClassPath()); + } + + @Test + void testFullyResolvedClassPath() throws Exception { + DependencyNode root = parse("simple.txt"); + DependencyVisitor fileSetter = new DependencyVisitor() { + @Override + public boolean visitEnter(DependencyNode node) { + node.setArtifact(node.getArtifact() + .setFile(new File(node.getDependency().getArtifact().getArtifactId()))); + return true; + } + + @Override + public boolean visitLeave(DependencyNode node) { + return true; + } + }; + root.accept(fileSetter); + + NodeListGenerator nodeListGenerator = new NodeListGenerator(); + LevelOrderDependencyNodeConsumerVisitor visitor = + new LevelOrderDependencyNodeConsumerVisitor(nodeListGenerator); + root.accept(visitor); + + Set fileNames = nodeListGenerator.getNodes().stream().map( )files.stream().map(File::getName).collect(Collectors.toSet()); + String classPath = nodeListGenerator.getClassPath(); + String[] splitClassPath = classPath.split(File.pathSeparator); + Set classPathNames = + Arrays.stream(splitClassPath).map(File::new).map(File::getName).collect(Collectors.toSet()); + + assertEquals(5, nodeListGenerator.getNodes().size()); + assertEquals(5, nodeListGenerator.getDependencies(false).size()); + assertEquals(5, nodeListGenerator.getDependencies(true).size()); + assertEquals(5, nodeListGenerator.getArtifacts(false).size()); + assertEquals(5, nodeListGenerator.getArtifacts(true).size()); + assertEquals(5, nodeListGenerator.getFiles().size()); + assertEquals(fileNames, classPathNames); + } + + @Test + void testIncompletelyResolvedEmptyClassPath() throws Exception { + DependencyNode root = parse("simple.txt"); + AtomicBoolean alternator = new AtomicBoolean(false); + HashSet fileNames = new HashSet<>(); + DependencyVisitor fileSetter = new DependencyVisitor() { + @Override + public boolean visitEnter(DependencyNode node) { + alternator.set(!alternator.get()); + if (alternator.get()) { + String fileName = node.getDependency().getArtifact().getArtifactId(); + fileNames.add(fileName); + node.setArtifact(node.getArtifact().setFile(new File(fileName))); + } + return true; + } + + @Override + public boolean visitLeave(DependencyNode node) { + return true; + } + }; + root.accept(fileSetter); + + NodeListGenerator nodeListGenerator = new NodeListGenerator(); + LevelOrderDependencyNodeConsumerVisitor visitor = + new LevelOrderDependencyNodeConsumerVisitor(nodeListGenerator); + root.accept(visitor); + + String classPath = nodeListGenerator.getClassPath(); + String[] splitClassPath = classPath.split(File.pathSeparator); + Set classPathNames = + Arrays.stream(splitClassPath).map(File::new).map(File::getName).collect(Collectors.toSet()); + + assertEquals(5, nodeListGenerator.getNodes().size()); + assertEquals(3, nodeListGenerator.getDependencies(false).size()); + assertEquals(5, nodeListGenerator.getDependencies(true).size()); + assertEquals(3, nodeListGenerator.getArtifacts(false).size()); + assertEquals(5, nodeListGenerator.getArtifacts(true).size()); + assertEquals(3, nodeListGenerator.getFiles().size()); + assertEquals(fileNames, classPathNames); + } } From 7f2f53023f2a4f6f18a9e33ff03e725737200101 Mon Sep 17 00:00:00 2001 From: Tamas Cservenak Date: Sat, 27 Jan 2024 12:42:51 +0100 Subject: [PATCH 2/3] Fix UT --- .../aether/util/graph/visitor/NodeListGeneratorTest.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/visitor/NodeListGeneratorTest.java b/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/visitor/NodeListGeneratorTest.java index ce30601a1..406375afc 100644 --- a/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/visitor/NodeListGeneratorTest.java +++ b/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/visitor/NodeListGeneratorTest.java @@ -22,6 +22,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; @@ -156,7 +157,11 @@ public boolean visitLeave(DependencyNode node) { new LevelOrderDependencyNodeConsumerVisitor(nodeListGenerator); root.accept(visitor); - Set fileNames = nodeListGenerator.getNodes().stream().map( )files.stream().map(File::getName).collect(Collectors.toSet()); + Set fileNames = nodeListGenerator.getNodes().stream() + .map(n -> n.getArtifact().getFile()) + .filter(Objects::nonNull) + .map(f -> f.getName()) + .collect(Collectors.toSet()); String classPath = nodeListGenerator.getClassPath(); String[] splitClassPath = classPath.split(File.pathSeparator); Set classPathNames = From c70716ea4347a5cb657961083d5955acf207cf03 Mon Sep 17 00:00:00 2001 From: Tamas Cservenak Date: Sat, 27 Jan 2024 14:17:45 +0100 Subject: [PATCH 3/3] Fixes --- .../aether/util/graph/visitor/NodeListGenerator.java | 6 +++--- .../aether/util/graph/visitor/NodeListGeneratorTest.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/visitor/NodeListGenerator.java b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/visitor/NodeListGenerator.java index faecbb1da..c4b38c33b 100644 --- a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/visitor/NodeListGenerator.java +++ b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/visitor/NodeListGenerator.java @@ -23,12 +23,12 @@ import java.util.List; import java.util.Objects; import java.util.function.Consumer; -import java.util.stream.Collectors; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.graph.DependencyNode; +import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; /** @@ -125,7 +125,7 @@ static List getDependencies(List nodes, boolean incl static List getArtifacts(List nodes, boolean includeUnresolved) { return getNodesWithDependencies(nodes).stream() - .map(DependencyNode::getArtifact) + .map(d -> d.getDependency().getArtifact()) .filter(artifact -> includeUnresolved || artifact.getFile() != null) .collect(toList()); } @@ -138,6 +138,6 @@ static List getFiles(List nodes) { } static String getClassPath(List nodes) { - return getFiles(nodes).stream().map(File::getAbsolutePath).collect(Collectors.joining(File.pathSeparator)); + return getFiles(nodes).stream().map(File::getAbsolutePath).collect(joining(File.pathSeparator)); } } diff --git a/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/visitor/NodeListGeneratorTest.java b/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/visitor/NodeListGeneratorTest.java index 406375afc..e8f59fec0 100644 --- a/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/visitor/NodeListGeneratorTest.java +++ b/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/visitor/NodeListGeneratorTest.java @@ -160,7 +160,7 @@ public boolean visitLeave(DependencyNode node) { Set fileNames = nodeListGenerator.getNodes().stream() .map(n -> n.getArtifact().getFile()) .filter(Objects::nonNull) - .map(f -> f.getName()) + .map(File::getName) .collect(Collectors.toSet()); String classPath = nodeListGenerator.getClassPath(); String[] splitClassPath = classPath.split(File.pathSeparator);