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