View Javadoc
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.util.ArrayList;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.function.Consumer;
26  
27  import org.eclipse.aether.artifact.Artifact;
28  import org.eclipse.aether.graph.Dependency;
29  import org.eclipse.aether.graph.DependencyNode;
30  
31  import static java.util.stream.Collectors.toList;
32  
33  /**
34   * Node list generator usable with different traversing strategies. It is wrapped {@link List}{@code <DependencyNode>} but
35   * offers several transformations, that are handy.
36   *
37   * @since 2.0.0
38   */
39  public final class NodeListGenerator implements Consumer<DependencyNode> {
40  
41      private final ArrayList<DependencyNode> nodes;
42  
43      public NodeListGenerator() {
44          nodes = new ArrayList<>(128);
45      }
46  
47      @Override
48      public void accept(DependencyNode dependencyNode) {
49          nodes.add(dependencyNode);
50      }
51  
52      /**
53       * Gets the list of dependency nodes that was generated during the graph traversal.
54       *
55       * @return The list of dependency nodes, never {@code null}.
56       */
57      public List<DependencyNode> getNodes() {
58          return nodes;
59      }
60  
61      /**
62       * Gets the list of dependency nodes that was generated during the graph traversal and have {@code non-null}
63       * {@link DependencyNode#getDependency()}.
64       *
65       * @return The list of dependency nodes having dependency, never {@code null}.
66       */
67      public List<DependencyNode> getNodesWithDependencies() {
68          return getNodesWithDependencies(getNodes());
69      }
70  
71      /**
72       * Gets the dependencies seen during the graph traversal.
73       *
74       * @param includeUnresolved Whether unresolved dependencies shall be included in the result or not.
75       * @return The list of dependencies, never {@code null}.
76       */
77      public List<Dependency> getDependencies(boolean includeUnresolved) {
78          return getDependencies(getNodes(), includeUnresolved);
79      }
80  
81      /**
82       * Gets the artifacts associated with the list of dependency nodes generated during the graph traversal.
83       *
84       * @param includeUnresolved Whether unresolved artifacts shall be included in the result or not.
85       * @return The list of artifacts, never {@code null}.
86       */
87      public List<Artifact> getArtifacts(boolean includeUnresolved) {
88          return getArtifacts(getNodes(), includeUnresolved);
89      }
90  
91      /**
92       * Gets the files of resolved artifacts seen during the graph traversal.
93       *
94       * @return The list of artifact files, never {@code null}.
95       */
96      public List<File> getFiles() {
97          return getFiles(getNodes());
98      }
99  
100     /**
101      * Gets a class path by concatenating the artifact files of the visited dependency nodes. Nodes with unresolved
102      * artifacts are automatically skipped.
103      *
104      * @return The class path, using the platform-specific path separator, never {@code null}.
105      */
106     public String getClassPath() {
107         return getClassPath(getNodes());
108     }
109 
110     static List<DependencyNode> getNodesWithDependencies(List<DependencyNode> nodes) {
111         return nodes.stream().filter(d -> d.getDependency() != null).collect(toList());
112     }
113 
114     static List<Dependency> getDependencies(List<DependencyNode> nodes, boolean includeUnresolved) {
115         List<Dependency> dependencies = new ArrayList<>(nodes.size());
116         for (DependencyNode node : getNodesWithDependencies(nodes)) {
117             Dependency dependency = node.getDependency();
118             if (includeUnresolved || dependency.getArtifact().getFile() != null) {
119                 dependencies.add(dependency);
120             }
121         }
122         return dependencies;
123     }
124 
125     static List<Artifact> getArtifacts(List<DependencyNode> nodes, boolean includeUnresolved) {
126         List<Artifact> artifacts = new ArrayList<>(nodes.size());
127         for (DependencyNode node : getNodesWithDependencies(nodes)) {
128             Artifact artifact = node.getDependency().getArtifact();
129             if (includeUnresolved || artifact.getFile() != null) {
130                 artifacts.add(artifact);
131             }
132         }
133 
134         return artifacts;
135     }
136 
137     static List<File> getFiles(List<DependencyNode> nodes) {
138         List<File> files = new ArrayList<>(nodes.size());
139         for (DependencyNode node : getNodesWithDependencies(nodes)) {
140             File file = node.getDependency().getArtifact().getFile();
141             if (file != null) {
142                 files.add(file);
143             }
144         }
145         return files;
146     }
147 
148     static String getClassPath(List<DependencyNode> nodes) {
149         StringBuilder buffer = new StringBuilder(1024);
150         for (Iterator<DependencyNode> it = getNodesWithDependencies(nodes).iterator(); it.hasNext(); ) {
151             DependencyNode node = it.next();
152             Artifact artifact = node.getDependency().getArtifact();
153             if (artifact.getFile() != null) {
154                 buffer.append(artifact.getFile().getAbsolutePath());
155                 if (it.hasNext()) {
156                     buffer.append(File.pathSeparatorChar);
157                 }
158             }
159         }
160         return buffer.toString();
161     }
162 }