Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 31 additions & 19 deletions api/maven-api-core/src/main/java/org/apache/maven/api/Artifact.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,76 +23,88 @@
import org.apache.maven.api.annotations.Nonnull;

/**
* An artifact points to a resource such as a jar file or war application.
* Pointer to a resolved resource such as a <abbr>JAR</abbr> file or <abbr>WAE</abbr> application.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't use resolved here imho. An Artifact may not be resolved / downloaded.
For example, the result of the DependencyResolver#collect() method will return a graph of Node, each one containing a Dependency (which extends Artifact), without having downloaded the related files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that "resolved" means that all properties were fixed to their final values, especially the version and obligation. Before resolution, an ArtifactCoordinate refers to an ensemble of files. After resolution, an Artifact refers to a single file. I was seeing the download as a separated concern. I have no problem in including download in the definition of "resolved", but maybe we should write this definition somewhere, e.g. in the package-info file.

* Each {@code Artifact} instance is basically a pointer to a file in the Maven repository.
* {@code Artifact} instances are created when <dfn>resolving</dfn> {@link ArtifactCoordinate} instances.
* Resolving is the process that selects a {@linkplain #getVersion() particular version}
* and downloads the artifact in the local repository.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So things are a bit blurry:

  • artifact resolution is: resolve version (see VersionResolver#resolveVersion()), and then resolve (i.e. download) the file
  • dependency resolution is: collect dependencies, flatten the graph, resolve (i.e. download) the file

During dependency collection, versions are resolved (@cstamas right?). The flattening phase removes branches of the graph so that one artifact per GA is present. The resolution phase will then download the result artifacts.

We don't have any way to download an artifact for which the version has been resolved though (that may be a missing bit). So if we introduce ResolvedArtifact and ResolvedDependency, it may help a bit:

  • version resolution: ArtifactCoordinate -> Artifact
  • artifact resolution: Artifact -> ResolvedArtifact
  • dependency collection -> Node + Dependency
  • dependency resolution: list of Dependency -> list of ResolvedDependency

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a "definitions of terms" section in package-info.java with the above explanation about artifact resolution and dependency resolution. Since those definitions include the download part, they answer my previous comment.

* The download may be deferred to the first time that the file is needed.
*
* @since 4.0.0
*/
@Experimental
@Immutable
public interface Artifact {

/**
* Returns a unique identifier for this artifact.
* {@return a unique identifier for this artifact}.
* The identifier is composed of groupId, artifactId, extension, classifier, and version.
*
* @return the unique identifier
* @see ArtifactCoordinate#getId()
*/
@Nonnull
default String key() {
String c = getClassifier();
return getGroupId()
+ ':'
+ getArtifactId()
+ ':'
+ getExtension()
+ (getClassifier().isEmpty() ? "" : ":" + getClassifier())
+ (c.isEmpty() ? "" : ":" + c)
+ ':'
+ getVersion();
}

/**
* The groupId of the artifact.
* {@return the group identifier of the artifact}.
*
* @return the groupId
* @see ArtifactCoordinate#getGroupId()
*/
@Nonnull
String getGroupId();

/**
* The artifactId of the artifact.
* {@return the identifier of the artifact}.
*
* @return the artifactId
* @see ArtifactCoordinate#getArtifactId()
*/
@Nonnull
String getArtifactId();

/**
* The version of the artifact.
* {@return the version of the artifact}. Contrarily to {@link ArtifactCoordinate},
* each {@code Artifact} is associated to a specific version instead of a range of versions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

range or meta version (LATEST, RELEASE, SNAPSHOT)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then the Version interface should said something about those meta-versions. I will put a first attempt, but it should be completed with an explanation of LATEST, RELEASE and SNAPSHOT semantic.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot that LATEST and RELEASE are actually deprecated. So we should not document them I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done the removal of LATEST and RELEASE from the documentation.

* If the {@linkplain #getBaseVersion() base version} contains a meta-version such as {@code SNAPSHOT},
* those keywords are replaced by, for example, the actual timestamp.
*
* @return the version
* @see ArtifactCoordinate#getVersionConstraint()
*/
@Nonnull
Version getVersion();

/**
* The base version of the artifact.
*
* @return the version
* {@return the version or meta-version of the artifact}.
* A meta-version is a version suffixed with the {@code SNAPSHOT} keyword.
* Meta-versions are represented in a base version by their symbols (e.g., {@code SNAPSHOT}),
* while they are replaced by, for example, the actual timestamp in the {@linkplain #getVersion() version}.
*/
@Nonnull
Version getBaseVersion();

/**
* The classifier of the artifact.
* Returns the classifier of the artifact.
*
* @return the classifier or an empty string if none, never {@code null}
* @see ArtifactCoordinate#getClassifier()
*/
@Nonnull
String getClassifier();

/**
* The file extension of the artifact.
* Returns the file extension of the artifact.
* The dot separator is <em>not</em> included in the returned string.
*
* @return the extension
* @return the file extension or an empty string if none, never {@code null}
* @see ArtifactCoordinate#getExtension()
*/
@Nonnull
String getExtension();
Expand All @@ -106,9 +118,9 @@ default String key() {
boolean isSnapshot();

/**
* Shortcut for {@code session.createArtifactCoordinate(artifact)}
* {@return coordinate with the same identifiers as this artifact}.
* This is a shortcut for {@code session.createArtifactCoordinate(artifact)}.
*
* @return an {@link ArtifactCoordinate}
* @see org.apache.maven.api.Session#createArtifactCoordinate(Artifact)
*/
@Nonnull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,64 +23,69 @@
import org.apache.maven.api.annotations.Nonnull;

/**
* The {@code Coordinate} object is used to point to an {@link Artifact}
* but the version may be specified as a range instead of an exact version.
* Identification of an ensemble of {@code Artifact}s in a range of versions.
* Each {@code ArtifactCoordinate} instance is basically a pointer to a file in the Maven repository,
* except that the version may not be defined precisely.
*
* @since 4.0.0
*/
@Experimental
@Immutable
public interface ArtifactCoordinate {

/**
* The groupId of the artifact.
*
* @return the groupId
* {@return the group identifier of the artifact}.
*/
@Nonnull
String getGroupId();

/**
* The artifactId of the artifact.
*
* @return the artifactId
* {@return the identifier of the artifact}.
*/
@Nonnull
String getArtifactId();

/**
* The classifier of the artifact.
* Returns the classifier of the artifact.
*
* @return the classifier or an empty string if none, never {@code null}
*/
@Nonnull
String getClassifier();

/**
* The version of the artifact.
*
* @return the version
* {@return the specific version, range of versions or meta-version of the artifact}.
* A meta-version is a version suffixed with the {@code SNAPSHOT} keyword.
*/
@Nonnull
VersionConstraint getVersion();
VersionConstraint getVersionConstraint();

/**
* The extension of the artifact.
* Returns the file extension of the artifact.
* The dot separator is <em>not</em> included in the returned string.
*
* @return the extension or an empty string if none, never {@code null}
* @return the file extension or an empty string if none, never {@code null}
*/
@Nonnull
String getExtension();

/**
* Unique id identifying this artifact
* {@return a unique string representation identifying this artifact}.
* The default implementation returns a colon-separated list of group
* identifier, artifact identifier, extension, classifier and version.
*
* @see Artifact#key()
*/
@Nonnull
default String getId() {
String c = getClassifier();
return getGroupId()
+ ":" + getArtifactId()
+ ":" + getExtension()
+ (getClassifier().isEmpty() ? "" : ":" + getClassifier())
+ ":" + getVersion();
+ ':'
+ getArtifactId()
+ ':'
+ getExtension()
+ ':'
+ c
+ (c.isEmpty() ? "" : ":")
+ getVersionConstraint();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,49 @@
import org.apache.maven.api.annotations.Nonnull;

/**
* A result of collecting, flattening and resolving {@code DependencyCoordinate}s.
* Dependency is the output of the <dfn>collection</dfn> process, which builds the graph of dependencies,
* followed by <dfn>flattening</dfn> and <dfn>resolution</dfn>.
* The version selection is done for each dependency during the collection phase.
* The flatten phase will keep only a single version per ({@code groupId}, {@code artifactId}) pair.
* The resolution will actually download the dependencies (or artifacts) that have been computed.
*
* @since 4.0.0
*/
@Experimental
@Immutable
public interface Dependency extends Artifact {

/**
* The dependency type.
* {@return the type of the dependency}. A dependency can be a <abbr>JAR</abbr> file,
* a modular-<abbr>JAR</abbr> if it is intended to be placed on the module-path,
* a <abbr>JAR</abbr> containing test classes, <i>etc.</i>
*
* @return the dependency type, never {@code null}
* @see DependencyCoordinate#getType()
*/
@Nonnull
Type getType();

/**
* {@return the time at which the dependency will be used}.
* If may be, for example, at compile time only, at run time or at test time.
*
* @see DependencyCoordinate#getScope()
*/
@Nonnull
DependencyScope getScope();

/**
* Returns whether the dependency is optional or mandatory.
* Contrarily to {@link DependencyCoordinate}, the obligation of a {@code Dependency} is always present.
* The value is computed during the dependencies collection phase.
*
* @return {@code true} if the dependency is optional, or {@code false} if mandatory
* @see DependencyCoordinate#getOptional()
*/
boolean isOptional();

/**
* Creates a {@code DependencyCoordinate} based on this {@code Dependency}.
*
* @return a {@link DependencyCoordinate}
* {@return coordinate with the same identifiers as this dependency}.
*/
@Nonnull
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,43 @@
import org.apache.maven.api.annotations.Nullable;

/**
* {@code ArtifactCoordinate} completed with information about how the artifact will be used.
* Those information include the dependency type (main classes, test classes, <i>etc.</i>),
* a scope (compile-time, run-time <i>etc.</i>), and an obligation (whether the dependency
* is optional or mandatory). The {@linkplain #getVersionConstraint() version}
* and the {@linkplain #getOptional() obligation} may not be defined precisely.
*
* @since 4.0.0
*/
@Experimental
@Immutable
public interface DependencyCoordinate extends ArtifactCoordinate {
/**
* The type of the artifact.
*
* @return the type
* {@return the type of the dependency}. A dependency can be a <abbr>JAR</abbr> file,
* a modular-<abbr>JAR</abbr> if it is intended to be placed on the module-path,
* a <abbr>JAR</abbr> containing test classes, <i>etc.</i>
*/
@Nonnull
Type getType();

/**
* {@return the time at which the dependency will be used}.
* If may be, for example, at compile time only, at run time or at test time.
*/
@Nonnull
DependencyScope getScope();

/**
* Returns whether the dependency is optional, mandatory or of unspecified obligation.
*
* @return the obligation, or {@code null} if unspecified
*/
@Nullable
Boolean getOptional();

/**
* {@return transitive dependencies to exclude}.
*/
@Nonnull
Collection<Exclusion> getExclusions();
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
import org.apache.maven.api.annotations.Nonnull;

/**
* Dependency scope.
* This represents at which time the dependency will be used, for example, at compile time only,
* at run time or at test time. For a given dependency, the scope is directly derived from the
* Indicates when the dependency will be used.
* For example, it may be at compile time only, at runtime, or at test time.
* For a given dependency, the scope is directly derived from the
* {@link org.apache.maven.api.model.Dependency#getScope()} and will be used when using {@link PathScope}
* and the {@link org.apache.maven.api.services.DependencyResolver}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -613,8 +613,8 @@ Map<PathType, List<Path>> resolveDependencies(
@Nonnull Project project, @Nonnull PathScope scope, @Nonnull Collection<PathType> desiredTypes);

/**
* Resolves an artifact's meta version (if any) to a concrete version. For example, resolves "1.0-SNAPSHOT"
* to "1.0-20090208.132618-23" or "RELEASE"/"LATEST" to "2.0".
* Resolves an artifact's meta version (if any) to a concrete version.
* For example, resolves "1.0-SNAPSHOT" to "1.0-20090208.132618-23".
* <p>
* Shortcut for {@code getService(VersionResolver.class).resolve(...)}
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
import org.apache.maven.api.annotations.Nonnull;

/**
* A version usually parsed using the {@link org.apache.maven.api.services.VersionParser} service.
* A version or meta-version of an artifact or a dependency.
* A meta-version is a version suffixed with the {@code SNAPSHOT} keyword.
* Version is usually parsed using the {@link org.apache.maven.api.services.VersionParser} service.
*
* @since 4.0.0
* @see org.apache.maven.api.services.VersionParser#parseVersion(String)
Expand Down
Loading