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.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 }