1 // =================== DO NOT EDIT THIS FILE ====================
2 // Generated by Modello Velocity from model.vm
3 // template, any modifications will be overwritten.
4 // ==============================================================
5 package org.apache.maven.api.model;
6
7 import java.io.Serializable;
8 import java.util.ArrayList;
9 import java.util.Collection;
10 import java.util.Collections;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Set;
15 import org.apache.maven.api.annotations.Experimental;
16 import org.apache.maven.api.annotations.Generated;
17 import org.apache.maven.api.annotations.Immutable;
18 import org.apache.maven.api.annotations.Nonnull;
19 import org.apache.maven.api.annotations.NotThreadSafe;
20 import org.apache.maven.api.annotations.ThreadSafe;
21
22 /**
23 * The {@code <dependency>} element contains information about a dependency
24 * of the project.
25 */
26 @Experimental
27 @Generated @ThreadSafe @Immutable
28 public class Dependency
29 implements Serializable, InputLocationTracker
30 {
31 /**
32 * The project group that produced the dependency, e.g.
33 * {@code org.apache.maven}.
34 */
35 final String groupId;
36 /**
37 * The unique id for an artifact produced by the project group, e.g.
38 * {@code maven-artifact}.
39 */
40 final String artifactId;
41 /**
42 * The version of the dependency, e.g. {@code 3.2.1}. Since Maven 2, this can also be
43 * specified as a range of versions.
44 */
45 final String version;
46 /**
47 * The type of dependency, that will be mapped to a file extension, an optional classifier, and a few other attributes.
48 * Some examples are {@code jar}, {@code war}, {@code ejb-client}
49 * and {@code test-jar}: see <a href="../maven-core/artifact-handlers.html">default
50 * artifact handlers</a> for a list. New types can be defined by extensions, so this is not a complete list.
51 */
52 final String type;
53 /**
54 * The classifier of the dependency. It is appended to
55 * the filename after the version. This allows:
56 * <ul>
57 * <li>referring to attached artifact, for example {@code sources} and {@code javadoc}:
58 * see <a href="../maven-core/artifact-handlers.html">default artifact handlers</a> for a list,</li>
59 * <li>distinguishing two artifacts
60 * that belong to the same POM but were built differently.
61 * For example, {@code jdk14} and {@code jdk15}.</li>
62 * </ul>
63 */
64 final String classifier;
65 /**
66 * The scope of the dependency - {@code compile}, {@code runtime},
67 * {@code test}, {@code system}, and {@code provided}. Used to
68 * calculate the various classpaths used for compilation, testing, and so on.
69 * It also assists in determining which artifacts to include in a distribution of
70 * this project. For more information, see
71 * <a href="https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html">the
72 * dependency mechanism</a>. The default scope is {@code compile}.
73 */
74 final String scope;
75 /**
76 * FOR SYSTEM SCOPE ONLY. Note that use of this property is <b>discouraged</b>
77 * and may be replaced in later versions. This specifies the path on the filesystem
78 * for this dependency.
79 * Requires an absolute path for the value, not relative.
80 * Use a property that gives the machine specific absolute path,
81 * e.g. {@code ${java.home}}.
82 */
83 final String systemPath;
84 /**
85 * Lists a set of artifacts that should be excluded from this dependency's
86 * artifact list when it comes to calculating transitive dependencies.
87 */
88 final List<Exclusion> exclusions;
89 /**
90 * Indicates the dependency is optional for use of this library. While the
91 * version of the dependency will be taken into account for dependency calculation if the
92 * library is used elsewhere, it will not be passed on transitively. Note: While the type
93 * of this field is {@code String} for technical reasons, the semantic type is actually
94 * {@code Boolean}. Default value is {@code false}.
95 */
96 final String optional;
97 /** Locations (this potentially hides the same name field from the super class) */
98 final Map<Object, InputLocation> locations;
99 /** Location tracking */
100 final InputLocation importedFrom;
101
102 /**
103 * Constructor for this class, to be called from its subclasses and {@link Builder}.
104 * @see Builder#build()
105 */
106 protected Dependency(Builder builder) {
107 this.groupId = builder.groupId != null ? builder.groupId : (builder.base != null ? builder.base.groupId : null);
108 this.artifactId = builder.artifactId != null ? builder.artifactId : (builder.base != null ? builder.base.artifactId : null);
109 this.version = builder.version != null ? builder.version : (builder.base != null ? builder.base.version : null);
110 this.type = builder.type != null ? builder.type : (builder.base != null ? builder.base.type : null);
111 this.classifier = builder.classifier != null ? builder.classifier : (builder.base != null ? builder.base.classifier : null);
112 this.scope = builder.scope != null ? builder.scope : (builder.base != null ? builder.base.scope : null);
113 this.systemPath = builder.systemPath != null ? builder.systemPath : (builder.base != null ? builder.base.systemPath : null);
114 this.exclusions = ImmutableCollections.copy(builder.exclusions != null ? builder.exclusions : (builder.base != null ? builder.base.exclusions : null));
115 this.optional = builder.optional != null ? builder.optional : (builder.base != null ? builder.base.optional : null);
116 Map<Object, InputLocation> newlocs = builder.locations != null ? builder.locations : Collections.emptyMap();
117 Map<Object, InputLocation> oldlocs = builder.base != null && builder.base.locations != null ? builder.base.locations : Collections.emptyMap();
118 Map<Object, InputLocation> mutableLocations = new HashMap<>();
119 this.importedFrom = builder.importedFrom;
120 mutableLocations.put("", newlocs.containsKey("") ? newlocs.get("") : oldlocs.get(""));
121 mutableLocations.put("groupId", newlocs.containsKey("groupId") ? newlocs.get("groupId") : oldlocs.get("groupId"));
122 mutableLocations.put("artifactId", newlocs.containsKey("artifactId") ? newlocs.get("artifactId") : oldlocs.get("artifactId"));
123 mutableLocations.put("version", newlocs.containsKey("version") ? newlocs.get("version") : oldlocs.get("version"));
124 mutableLocations.put("type", newlocs.containsKey("type") ? newlocs.get("type") : oldlocs.get("type"));
125 mutableLocations.put("classifier", newlocs.containsKey("classifier") ? newlocs.get("classifier") : oldlocs.get("classifier"));
126 mutableLocations.put("scope", newlocs.containsKey("scope") ? newlocs.get("scope") : oldlocs.get("scope"));
127 mutableLocations.put("systemPath", newlocs.containsKey("systemPath") ? newlocs.get("systemPath") : oldlocs.get("systemPath"));
128 mutableLocations.put("exclusions", newlocs.containsKey("exclusions") ? newlocs.get("exclusions") : oldlocs.get("exclusions"));
129 mutableLocations.put("optional", newlocs.containsKey("optional") ? newlocs.get("optional") : oldlocs.get("optional"));
130 this.locations = Collections.unmodifiableMap(mutableLocations);
131 }
132
133 /**
134 * The project group that produced the dependency, e.g.
135 * {@code org.apache.maven}.
136 *
137 * @return a {@code String}
138 */
139 public String getGroupId() {
140 return this.groupId;
141 }
142
143 /**
144 * The unique id for an artifact produced by the project group, e.g.
145 * {@code maven-artifact}.
146 *
147 * @return a {@code String}
148 */
149 public String getArtifactId() {
150 return this.artifactId;
151 }
152
153 /**
154 * The version of the dependency, e.g. {@code 3.2.1}. Since Maven 2, this can also be
155 * specified as a range of versions.
156 *
157 * @return a {@code String}
158 */
159 public String getVersion() {
160 return this.version;
161 }
162
163 /**
164 * The type of dependency, that will be mapped to a file extension, an optional classifier, and a few other attributes.
165 * Some examples are {@code jar}, {@code war}, {@code ejb-client}
166 * and {@code test-jar}: see <a href="../maven-core/artifact-handlers.html">default
167 * artifact handlers</a> for a list. New types can be defined by extensions, so this is not a complete list.
168 *
169 * @return a {@code String}
170 */
171 public String getType() {
172 return this.type;
173 }
174
175 /**
176 * The classifier of the dependency. It is appended to
177 * the filename after the version. This allows:
178 * <ul>
179 * <li>referring to attached artifact, for example {@code sources} and {@code javadoc}:
180 * see <a href="../maven-core/artifact-handlers.html">default artifact handlers</a> for a list,</li>
181 * <li>distinguishing two artifacts
182 * that belong to the same POM but were built differently.
183 * For example, {@code jdk14} and {@code jdk15}.</li>
184 * </ul>
185 *
186 * @return a {@code String}
187 */
188 public String getClassifier() {
189 return this.classifier;
190 }
191
192 /**
193 * The scope of the dependency - {@code compile}, {@code runtime},
194 * {@code test}, {@code system}, and {@code provided}. Used to
195 * calculate the various classpaths used for compilation, testing, and so on.
196 * It also assists in determining which artifacts to include in a distribution of
197 * this project. For more information, see
198 * <a href="https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html">the
199 * dependency mechanism</a>. The default scope is {@code compile}.
200 *
201 * @return a {@code String}
202 */
203 public String getScope() {
204 return this.scope;
205 }
206
207 /**
208 * FOR SYSTEM SCOPE ONLY. Note that use of this property is <b>discouraged</b>
209 * and may be replaced in later versions. This specifies the path on the filesystem
210 * for this dependency.
211 * Requires an absolute path for the value, not relative.
212 * Use a property that gives the machine specific absolute path,
213 * e.g. {@code ${java.home}}.
214 *
215 * @return a {@code String}
216 */
217 public String getSystemPath() {
218 return this.systemPath;
219 }
220
221 /**
222 * Lists a set of artifacts that should be excluded from this dependency's
223 * artifact list when it comes to calculating transitive dependencies.
224 *
225 * @return a {@code List<Exclusion>}
226 */
227 @Nonnull
228 public List<Exclusion> getExclusions() {
229 return this.exclusions;
230 }
231
232 /**
233 * Indicates the dependency is optional for use of this library. While the
234 * version of the dependency will be taken into account for dependency calculation if the
235 * library is used elsewhere, it will not be passed on transitively. Note: While the type
236 * of this field is {@code String} for technical reasons, the semantic type is actually
237 * {@code Boolean}. Default value is {@code false}.
238 *
239 * @return a {@code String}
240 */
241 public String getOptional() {
242 return this.optional;
243 }
244
245 /**
246 * Gets the location of the specified field in the input source.
247 */
248 public InputLocation getLocation(Object key) {
249 return locations != null ? locations.get(key) : null;
250 }
251
252 /**
253 * Gets the keys of the locations of the input source.
254 */
255 public Set<Object> getLocationKeys() {
256 return locations != null ? locations.keySet() : null;
257 }
258
259 /**
260 * Gets the input location that caused this model to be read.
261 */
262 public InputLocation getImportedFrom()
263 {
264 return importedFrom;
265 }
266
267 /**
268 * Creates a new builder with this object as the basis.
269 *
270 * @return a {@code Builder}
271 */
272 @Nonnull
273 public Builder with() {
274 return newBuilder(this);
275 }
276 /**
277 * Creates a new {@code Dependency} instance using the specified groupId.
278 *
279 * @param groupId the new {@code String} to use
280 * @return a {@code Dependency} with the specified groupId
281 */
282 @Nonnull
283 public Dependency withGroupId(String groupId) {
284 return newBuilder(this, true).groupId(groupId).build();
285 }
286 /**
287 * Creates a new {@code Dependency} instance using the specified artifactId.
288 *
289 * @param artifactId the new {@code String} to use
290 * @return a {@code Dependency} with the specified artifactId
291 */
292 @Nonnull
293 public Dependency withArtifactId(String artifactId) {
294 return newBuilder(this, true).artifactId(artifactId).build();
295 }
296 /**
297 * Creates a new {@code Dependency} instance using the specified version.
298 *
299 * @param version the new {@code String} to use
300 * @return a {@code Dependency} with the specified version
301 */
302 @Nonnull
303 public Dependency withVersion(String version) {
304 return newBuilder(this, true).version(version).build();
305 }
306 /**
307 * Creates a new {@code Dependency} instance using the specified type.
308 *
309 * @param type the new {@code String} to use
310 * @return a {@code Dependency} with the specified type
311 */
312 @Nonnull
313 public Dependency withType(String type) {
314 return newBuilder(this, true).type(type).build();
315 }
316 /**
317 * Creates a new {@code Dependency} instance using the specified classifier.
318 *
319 * @param classifier the new {@code String} to use
320 * @return a {@code Dependency} with the specified classifier
321 */
322 @Nonnull
323 public Dependency withClassifier(String classifier) {
324 return newBuilder(this, true).classifier(classifier).build();
325 }
326 /**
327 * Creates a new {@code Dependency} instance using the specified scope.
328 *
329 * @param scope the new {@code String} to use
330 * @return a {@code Dependency} with the specified scope
331 */
332 @Nonnull
333 public Dependency withScope(String scope) {
334 return newBuilder(this, true).scope(scope).build();
335 }
336 /**
337 * Creates a new {@code Dependency} instance using the specified systemPath.
338 *
339 * @param systemPath the new {@code String} to use
340 * @return a {@code Dependency} with the specified systemPath
341 */
342 @Nonnull
343 public Dependency withSystemPath(String systemPath) {
344 return newBuilder(this, true).systemPath(systemPath).build();
345 }
346 /**
347 * Creates a new {@code Dependency} instance using the specified exclusions.
348 *
349 * @param exclusions the new {@code Collection<Exclusion>} to use
350 * @return a {@code Dependency} with the specified exclusions
351 */
352 @Nonnull
353 public Dependency withExclusions(Collection<Exclusion> exclusions) {
354 return newBuilder(this, true).exclusions(exclusions).build();
355 }
356 /**
357 * Creates a new {@code Dependency} instance using the specified optional.
358 *
359 * @param optional the new {@code String} to use
360 * @return a {@code Dependency} with the specified optional
361 */
362 @Nonnull
363 public Dependency withOptional(String optional) {
364 return newBuilder(this, true).optional(optional).build();
365 }
366
367 /**
368 * Creates a new {@code Dependency} instance.
369 * Equivalent to {@code newInstance(true)}.
370 * @see #newInstance(boolean)
371 *
372 * @return a new {@code Dependency}
373 */
374 @Nonnull
375 public static Dependency newInstance() {
376 return newInstance(true);
377 }
378
379 /**
380 * Creates a new {@code Dependency} instance using default values or not.
381 * Equivalent to {@code newBuilder(withDefaults).build()}.
382 *
383 * @param withDefaults the boolean indicating whether default values should be used
384 * @return a new {@code Dependency}
385 */
386 @Nonnull
387 public static Dependency newInstance(boolean withDefaults) {
388 return newBuilder(withDefaults).build();
389 }
390
391 /**
392 * Creates a new {@code Dependency} builder instance.
393 * Equivalent to {@code newBuilder(true)}.
394 * @see #newBuilder(boolean)
395 *
396 * @return a new {@code Builder}
397 */
398 @Nonnull
399 public static Builder newBuilder() {
400 return newBuilder(true);
401 }
402
403 /**
404 * Creates a new {@code Dependency} builder instance using default values or not.
405 *
406 * @param withDefaults the boolean indicating whether default values should be used
407 * @return a new {@code Builder}
408 */
409 @Nonnull
410 public static Builder newBuilder(boolean withDefaults) {
411 return new Builder(withDefaults);
412 }
413
414 /**
415 * Creates a new {@code Dependency} builder instance using the specified object as a basis.
416 * Equivalent to {@code newBuilder(from, false)}.
417 *
418 * @param from the {@code Dependency} instance to use as a basis
419 * @return a new {@code Builder}
420 */
421 @Nonnull
422 public static Builder newBuilder(Dependency from) {
423 return newBuilder(from, false);
424 }
425
426 /**
427 * Creates a new {@code Dependency} builder instance using the specified object as a basis.
428 *
429 * @param from the {@code Dependency} instance to use as a basis
430 * @param forceCopy the boolean indicating if a copy should be forced
431 * @return a new {@code Builder}
432 */
433 @Nonnull
434 public static Builder newBuilder(Dependency from, boolean forceCopy) {
435 return new Builder(from, forceCopy);
436 }
437
438 /**
439 * Builder class used to create Dependency instances.
440 * @see #with()
441 * @see #newBuilder()
442 */
443 @NotThreadSafe
444 public static class Builder
445 {
446 Dependency base;
447 String groupId;
448 String artifactId;
449 String version;
450 String type;
451 String classifier;
452 String scope;
453 String systemPath;
454 Collection<Exclusion> exclusions;
455 String optional;
456 Map<Object, InputLocation> locations;
457 InputLocation importedFrom;
458
459 protected Builder(boolean withDefaults) {
460 if (withDefaults) {
461 this.type = "jar";
462 }
463 }
464
465 protected Builder(Dependency base, boolean forceCopy) {
466 if (forceCopy) {
467 this.groupId = base.groupId;
468 this.artifactId = base.artifactId;
469 this.version = base.version;
470 this.type = base.type;
471 this.classifier = base.classifier;
472 this.scope = base.scope;
473 this.systemPath = base.systemPath;
474 this.exclusions = base.exclusions;
475 this.optional = base.optional;
476 this.locations = base.locations;
477 this.importedFrom = base.importedFrom;
478 } else {
479 this.base = base;
480 }
481 }
482
483 @Nonnull
484 public Builder groupId(String groupId) {
485 this.groupId = groupId;
486 return this;
487 }
488
489 @Nonnull
490 public Builder artifactId(String artifactId) {
491 this.artifactId = artifactId;
492 return this;
493 }
494
495 @Nonnull
496 public Builder version(String version) {
497 this.version = version;
498 return this;
499 }
500
501 @Nonnull
502 public Builder type(String type) {
503 this.type = type;
504 return this;
505 }
506
507 @Nonnull
508 public Builder classifier(String classifier) {
509 this.classifier = classifier;
510 return this;
511 }
512
513 @Nonnull
514 public Builder scope(String scope) {
515 this.scope = scope;
516 return this;
517 }
518
519 @Nonnull
520 public Builder systemPath(String systemPath) {
521 this.systemPath = systemPath;
522 return this;
523 }
524
525 @Nonnull
526 public Builder exclusions(Collection<Exclusion> exclusions) {
527 this.exclusions = exclusions;
528 return this;
529 }
530
531 @Nonnull
532 public Builder optional(String optional) {
533 this.optional = optional;
534 return this;
535 }
536
537
538 @Nonnull
539 public Builder location(Object key, InputLocation location) {
540 if (location != null) {
541 if (!(this.locations instanceof HashMap)) {
542 this.locations = this.locations != null ? new HashMap<>(this.locations) : new HashMap<>();
543 }
544 this.locations.put(key, location);
545 }
546 return this;
547 }
548
549 @Nonnull
550 public Builder importedFrom(InputLocation importedFrom) {
551 this.importedFrom = importedFrom;
552 return this;
553 }
554
555 @Nonnull
556 public Dependency build() {
557 // this method should not contain any logic other than creating (or reusing) an object in order to ease subclassing
558 if (base != null
559 && (groupId == null || groupId == base.groupId)
560 && (artifactId == null || artifactId == base.artifactId)
561 && (version == null || version == base.version)
562 && (type == null || type == base.type)
563 && (classifier == null || classifier == base.classifier)
564 && (scope == null || scope == base.scope)
565 && (systemPath == null || systemPath == base.systemPath)
566 && (exclusions == null || exclusions == base.exclusions)
567 && (optional == null || optional == base.optional)
568 ) {
569 return base;
570 }
571 return new Dependency(this);
572 }
573 }
574
575
576
577 public boolean isOptional() {
578 return (getOptional() != null) ? Boolean.parseBoolean(getOptional()) : false;
579 }
580
581
582
583
584
585 /**
586 * @see java.lang.Object#toString()
587 */
588 public String toString() {
589 return "Dependency {groupId=" + getGroupId() + ", artifactId=" + getArtifactId() + ", version=" + getVersion() + ", type=" + getType() + "}";
590 }
591
592
593
594
595 private volatile String managementKey;
596
597 /**
598 * @return the management key as {@code groupId:artifactId:type}
599 */
600 public String getManagementKey() {
601 if (managementKey == null) {
602 managementKey = getGroupId() + ":" + getArtifactId() + ":" + getType() + (getClassifier() != null ? ":" + getClassifier() : "");
603 }
604 return managementKey;
605 }
606
607
608 }