1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.eclipse.aether.util.graph.visitor;
20
21 import java.io.File;
22 import java.nio.file.Path;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.Objects;
26 import java.util.function.Consumer;
27
28 import org.eclipse.aether.artifact.Artifact;
29 import org.eclipse.aether.graph.Dependency;
30 import org.eclipse.aether.graph.DependencyNode;
31
32 import static java.util.stream.Collectors.joining;
33 import static java.util.stream.Collectors.toList;
34
35 /**
36 * Node list generator usable with different traversing strategies. It is wrapped {@link List}{@code <DependencyNode>} but
37 * offers several transformations, that are handy.
38 *
39 * @since 2.0.0
40 *
41 * @see PreorderDependencyNodeConsumerVisitor
42 * @see PostorderDependencyNodeConsumerVisitor
43 * @see LevelOrderDependencyNodeConsumerVisitor
44 */
45 public final class NodeListGenerator implements Consumer<DependencyNode> {
46
47 private final ArrayList<DependencyNode> nodes;
48
49 public NodeListGenerator() {
50 nodes = new ArrayList<>(128);
51 }
52
53 @Override
54 public void accept(DependencyNode dependencyNode) {
55 nodes.add(dependencyNode);
56 }
57
58 /**
59 * Gets the list of dependency nodes that was generated during the graph traversal.
60 *
61 * @return The list of dependency nodes, never {@code null}.
62 */
63 public List<DependencyNode> getNodes() {
64 return nodes;
65 }
66
67 /**
68 * Gets the list of dependency nodes that was generated during the graph traversal and have {@code non-null}
69 * {@link DependencyNode#getDependency()}.
70 *
71 * @return The list of dependency nodes having dependency, never {@code null}.
72 */
73 public List<DependencyNode> getNodesWithDependencies() {
74 return getNodesWithDependencies(getNodes());
75 }
76
77 /**
78 * Gets the dependencies seen during the graph traversal.
79 *
80 * @param includeUnresolved Whether unresolved dependencies shall be included in the result or not.
81 * @return The list of dependencies, never {@code null}.
82 */
83 public List<Dependency> getDependencies(boolean includeUnresolved) {
84 return getDependencies(getNodes(), includeUnresolved);
85 }
86
87 /**
88 * Gets the artifacts associated with the list of dependency nodes generated during the graph traversal.
89 *
90 * @param includeUnresolved Whether unresolved artifacts shall be included in the result or not.
91 * @return The list of artifacts, never {@code null}.
92 */
93 public List<Artifact> getArtifacts(boolean includeUnresolved) {
94 return getArtifacts(getNodes(), includeUnresolved);
95 }
96
97 /**
98 * Gets the files of resolved artifacts seen during the graph traversal.
99 *
100 * @return The list of artifact files, never {@code null}.
101 * @deprecated Use {@link #getPaths()} instead.
102 */
103 @Deprecated
104 public List<File> getFiles() {
105 return getFiles(getNodes());
106 }
107
108 /**
109 * Gets the files of resolved artifacts seen during the graph traversal.
110 *
111 * @return The list of artifact files, never {@code null}.
112 * @since 2.0.0
113 */
114 public List<Path> getPaths() {
115 return getPaths(getNodes());
116 }
117
118 /**
119 * Gets a class path by concatenating the artifact files of the visited dependency nodes. Nodes with unresolved
120 * artifacts are automatically skipped.
121 *
122 * @return The class path, using the platform-specific path separator, never {@code null}.
123 */
124 public String getClassPath() {
125 return getClassPath(getNodes());
126 }
127
128 static List<DependencyNode> getNodesWithDependencies(List<DependencyNode> nodes) {
129 return nodes.stream().filter(d -> d.getDependency() != null).collect(toList());
130 }
131
132 static List<Dependency> getDependencies(List<DependencyNode> nodes, boolean includeUnresolved) {
133 return getNodesWithDependencies(nodes).stream()
134 .map(DependencyNode::getDependency)
135 .filter(d -> includeUnresolved || d.getArtifact().getPath() != null)
136 .collect(toList());
137 }
138
139 static List<Artifact> getArtifacts(List<DependencyNode> nodes, boolean includeUnresolved) {
140 return getNodesWithDependencies(nodes).stream()
141 .map(d -> d.getDependency().getArtifact())
142 .filter(artifact -> includeUnresolved || artifact.getPath() != null)
143 .collect(toList());
144 }
145
146 @Deprecated
147 static List<File> getFiles(List<DependencyNode> nodes) {
148 return getNodesWithDependencies(nodes).stream()
149 .map(d -> d.getDependency().getArtifact().getFile())
150 .filter(Objects::nonNull)
151 .collect(toList());
152 }
153
154 static List<Path> getPaths(List<DependencyNode> nodes) {
155 return getNodesWithDependencies(nodes).stream()
156 .map(d -> d.getDependency().getArtifact().getPath())
157 .filter(Objects::nonNull)
158 .collect(toList());
159 }
160
161 static String getClassPath(List<DependencyNode> nodes) {
162 return getPaths(nodes).stream()
163 .map(Path::toAbsolutePath)
164 .map(Path::toString)
165 .collect(joining(File.pathSeparator));
166 }
167 }