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