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.collection;
20
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.List;
24
25 import org.eclipse.aether.RepositorySystem;
26 import org.eclipse.aether.RequestTrace;
27 import org.eclipse.aether.artifact.Artifact;
28 import org.eclipse.aether.graph.Dependency;
29 import org.eclipse.aether.repository.RemoteRepository;
30 import org.eclipse.aether.scope.ResolutionScope;
31
32 /**
33 * A request to collect the transitive dependencies and to build a dependency graph from them. There are three ways to
34 * create a dependency graph. First, only the root dependency can be given. Second, a root dependency and direct
35 * dependencies can be specified in which case the specified direct dependencies are merged with the direct dependencies
36 * retrieved from the artifact descriptor of the root dependency. And last, only direct dependencies can be specified in
37 * which case the root node of the resulting graph has no associated dependency.
38 *
39 * @see RepositorySystem#collectDependencies(org.eclipse.aether.RepositorySystemSession, CollectRequest)
40 */
41 public final class CollectRequest {
42 private ResolutionScope resolutionScope;
43
44 private Artifact rootArtifact;
45
46 private Dependency root;
47
48 private List<Dependency> dependencies = Collections.emptyList();
49
50 private List<Dependency> managedDependencies = Collections.emptyList();
51
52 private List<RemoteRepository> repositories = Collections.emptyList();
53
54 private String context = "";
55
56 private RequestTrace trace;
57
58 /**
59 * Creates an uninitialized request.
60 */
61 public CollectRequest() {
62 // enables default constructor
63 }
64
65 /**
66 * Creates a request with the specified properties.
67 *
68 * @param root The root dependency whose transitive dependencies should be collected, may be {@code null}.
69 * @param repositories The repositories to use for the collection, may be {@code null}.
70 */
71 public CollectRequest(Dependency root, List<RemoteRepository> repositories) {
72 setRoot(root);
73 setRepositories(repositories);
74 }
75
76 /**
77 * Creates a new request with the specified properties.
78 *
79 * @param root The root dependency whose transitive dependencies should be collected, may be {@code null}.
80 * @param dependencies The direct dependencies to merge with the direct dependencies from the root dependency's
81 * artifact descriptor.
82 * @param repositories The repositories to use for the collection, may be {@code null}.
83 */
84 public CollectRequest(Dependency root, List<Dependency> dependencies, List<RemoteRepository> repositories) {
85 setRoot(root);
86 setDependencies(dependencies);
87 setRepositories(repositories);
88 }
89
90 /**
91 * Creates a new request with the specified properties.
92 *
93 * @param dependencies The direct dependencies of some imaginary root, may be {@code null}.
94 * @param managedDependencies The dependency management information to apply to the transitive dependencies, may be
95 * {@code null}.
96 * @param repositories The repositories to use for the collection, may be {@code null}.
97 */
98 public CollectRequest(
99 List<Dependency> dependencies, List<Dependency> managedDependencies, List<RemoteRepository> repositories) {
100 setDependencies(dependencies);
101 setManagedDependencies(managedDependencies);
102 setRepositories(repositories);
103 }
104
105 /**
106 * Gets the wanted resolution scope. If set, the {@link org.eclipse.aether.scope.ScopeManager} has to be set on
107 * session as well, otherwise it is considered user error: misconfigured collect request.
108 *
109 * @since 2.0.0
110 * @return The wanted resolution scope.
111 */
112 public ResolutionScope getResolutionScope() {
113 return resolutionScope;
114 }
115
116 /**
117 * Sets the wanted resolution scope. Usable only if {@link org.eclipse.aether.scope.ScopeManager} is used.
118 *
119 * @since 2.0.0
120 * @param resolutionScope The wanted resolution scope, may be {@code null} to "drive by yourself".
121 */
122 public void setResolutionScope(ResolutionScope resolutionScope) {
123 this.resolutionScope = resolutionScope;
124 }
125
126 /**
127 * Gets the root artifact for the dependency graph.
128 *
129 * @return The root artifact for the dependency graph or {@code null} if none.
130 */
131 public Artifact getRootArtifact() {
132 return rootArtifact;
133 }
134
135 /**
136 * Sets the root artifact for the dependency graph. This must not be confused with {@link #setRoot(Dependency)}: The
137 * root <em>dependency</em>, like any other specified dependency, will be subject to dependency
138 * collection/resolution, i.e. should have an artifact descriptor and a corresponding artifact file. The root
139 * <em>artifact</em> on the other hand is only used as a label for the root node of the graph in case no root
140 * dependency was specified. As such, the configured root artifact is ignored if {@link #getRoot()} does not return
141 * {@code null}.
142 *
143 * @param rootArtifact The root artifact for the dependency graph, may be {@code null}.
144 * @return This request for chaining, never {@code null}.
145 */
146 public CollectRequest setRootArtifact(Artifact rootArtifact) {
147 this.rootArtifact = rootArtifact;
148 return this;
149 }
150
151 /**
152 * Gets the root dependency of the graph.
153 *
154 * @return The root dependency of the graph or {@code null} if none.
155 */
156 public Dependency getRoot() {
157 return root;
158 }
159
160 /**
161 * Sets the root dependency of the graph.
162 *
163 * @param root The root dependency of the graph, may be {@code null}.
164 * @return This request for chaining, never {@code null}.
165 */
166 public CollectRequest setRoot(Dependency root) {
167 this.root = root;
168 return this;
169 }
170
171 /**
172 * Gets the direct dependencies.
173 *
174 * @return The direct dependencies, never {@code null}.
175 */
176 public List<Dependency> getDependencies() {
177 return dependencies;
178 }
179
180 /**
181 * Sets the direct dependencies. If both a root dependency and direct dependencies are given in the request, the
182 * direct dependencies from the request will be merged with the direct dependencies from the root dependency's
183 * artifact descriptor, giving higher priority to the dependencies from the request.
184 *
185 * @param dependencies The direct dependencies, may be {@code null}.
186 * @return This request for chaining, never {@code null}.
187 */
188 public CollectRequest setDependencies(List<Dependency> dependencies) {
189 if (dependencies == null) {
190 this.dependencies = Collections.emptyList();
191 } else {
192 this.dependencies = dependencies;
193 }
194 return this;
195 }
196
197 /**
198 * Adds the specified direct dependency.
199 *
200 * @param dependency The dependency to add, may be {@code null}.
201 * @return This request for chaining, never {@code null}.
202 */
203 public CollectRequest addDependency(Dependency dependency) {
204 if (dependency != null) {
205 if (this.dependencies.isEmpty()) {
206 this.dependencies = new ArrayList<>();
207 }
208 this.dependencies.add(dependency);
209 }
210 return this;
211 }
212
213 /**
214 * Gets the dependency management to apply to transitive dependencies.
215 *
216 * @return The dependency management to apply to transitive dependencies, never {@code null}.
217 */
218 public List<Dependency> getManagedDependencies() {
219 return managedDependencies;
220 }
221
222 /**
223 * Sets the dependency management to apply to transitive dependencies. To clarify, this management does not apply to
224 * the direct dependencies of the root node.
225 *
226 * @param managedDependencies The dependency management, may be {@code null}.
227 * @return This request for chaining, never {@code null}.
228 */
229 public CollectRequest setManagedDependencies(List<Dependency> managedDependencies) {
230 if (managedDependencies == null) {
231 this.managedDependencies = Collections.emptyList();
232 } else {
233 this.managedDependencies = managedDependencies;
234 }
235 return this;
236 }
237
238 /**
239 * Adds the specified managed dependency.
240 *
241 * @param managedDependency The managed dependency to add, may be {@code null}.
242 * @return This request for chaining, never {@code null}.
243 */
244 public CollectRequest addManagedDependency(Dependency managedDependency) {
245 if (managedDependency != null) {
246 if (this.managedDependencies.isEmpty()) {
247 this.managedDependencies = new ArrayList<>();
248 }
249 this.managedDependencies.add(managedDependency);
250 }
251 return this;
252 }
253
254 /**
255 * Gets the repositories to use for the collection.
256 *
257 * @return The repositories to use for the collection, never {@code null}.
258 */
259 public List<RemoteRepository> getRepositories() {
260 return repositories;
261 }
262
263 /**
264 * Sets the repositories to use for the collection.
265 *
266 * @param repositories The repositories to use for the collection, may be {@code null}.
267 * @return This request for chaining, never {@code null}.
268 */
269 public CollectRequest setRepositories(List<RemoteRepository> repositories) {
270 if (repositories == null) {
271 this.repositories = Collections.emptyList();
272 } else {
273 this.repositories = repositories;
274 }
275 return this;
276 }
277
278 /**
279 * Adds the specified repository for collection.
280 *
281 * @param repository The repository to collect dependency information from, may be {@code null}.
282 * @return This request for chaining, never {@code null}.
283 */
284 public CollectRequest addRepository(RemoteRepository repository) {
285 if (repository != null) {
286 if (this.repositories.isEmpty()) {
287 this.repositories = new ArrayList<>();
288 }
289 this.repositories.add(repository);
290 }
291 return this;
292 }
293
294 /**
295 * Gets the context in which this request is made.
296 *
297 * @return The context, never {@code null}.
298 */
299 public String getRequestContext() {
300 return context;
301 }
302
303 /**
304 * Sets the context in which this request is made.
305 *
306 * @param context The context, may be {@code null}.
307 * @return This request for chaining, never {@code null}.
308 */
309 public CollectRequest setRequestContext(String context) {
310 this.context = (context != null) ? context : "";
311 return this;
312 }
313
314 /**
315 * Gets the trace information that describes the higher level request/operation in which this request is issued.
316 *
317 * @return The trace information about the higher level operation or {@code null} if none.
318 */
319 public RequestTrace getTrace() {
320 return trace;
321 }
322
323 /**
324 * Sets the trace information that describes the higher level request/operation in which this request is issued.
325 *
326 * @param trace The trace information about the higher level operation, may be {@code null}.
327 * @return This request for chaining, never {@code null}.
328 */
329 public CollectRequest setTrace(RequestTrace trace) {
330 this.trace = trace;
331 return this;
332 }
333
334 @Override
335 public String toString() {
336 return getRoot() + " -> " + getDependencies() + " < " + getRepositories();
337 }
338 }