diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java b/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java
index 83d028b3ce..4a3409233c 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java
@@ -37,24 +37,85 @@ import org.apache.maven.api.model.Model;
@Experimental
public interface Project {
+ /**
+ * Returns the project groupId.
+ */
@Nonnull
String getGroupId();
+ /**
+ * Returns the project artifactId.
+ */
@Nonnull
String getArtifactId();
+ /**
+ * Returns the project version.
+ */
@Nonnull
String getVersion();
+ /**
+ * Returns the project packaging.
+ *
+ * Note: unlike in legacy code, logical checks against string representing packaging (returned by this method)
+ * are NOT recommended (code like {@code "pom".equals(project.getPackaging)} must be avoided). Use method
+ * {@link #getArtifacts()} to gain access to POM or build artifact.
+ *
+ * @see #getArtifacts()
+ */
@Nonnull
String getPackaging();
+ /**
+ * Returns the project POM artifact, which is the artifact of the POM of this project. Every project have a POM
+ * artifact, even if the existence of backing POM file is NOT a requirement (i.e. for some transient projects).
+ *
+ * @see org.apache.maven.api.services.ArtifactManager#getPath(Artifact)
+ */
@Nonnull
- Artifact getArtifact();
+ default Artifact getPomArtifact() {
+ return getArtifacts().get(0);
+ }
+ /**
+ * Returns the project main artifact, which is the artifact produced by this project build, if applicable.
+ * This artifact MAY be absent if the project is actually not producing any main artifact (i.e. "pom" packaging).
+ *
+ * @see #getPackaging()
+ * @see org.apache.maven.api.services.ArtifactManager#getPath(Artifact)
+ */
+ @Nonnull
+ default Optional getMainArtifact() {
+ List artifacts = getArtifacts();
+ return artifacts.size() == 2 ? Optional.of(artifacts.get(1)) : Optional.empty();
+ }
+
+ /**
+ * Returns the project artifacts as immutable list. Elements are the project POM artifact and the artifact
+ * produced by this project build, if applicable. Hence, the returned list may have one or two elements
+ * (never less than 1, never more than 2), depending on project packaging.
+ *
+ * The list's first element is ALWAYS the project POM artifact. Presence of second element in the list depends
+ * solely on the project packaging.
+ *
+ * @see #getPackaging()
+ * @see #getPomArtifact()
+ * @see #getMainArtifact()
+ * @see org.apache.maven.api.services.ArtifactManager#getPath(Artifact)
+ */
+ @Nonnull
+ List getArtifacts();
+
+ /**
+ * Returns the project model.
+ */
@Nonnull
Model getModel();
+ /**
+ * Shorthand method.
+ */
@Nonnull
default Build getBuild() {
Build build = getModel().getBuild();
@@ -71,17 +132,35 @@ public interface Project {
@Nonnull
Optional getPomPath();
+ /**
+ * Returns the project base directory.
+ */
@Nonnull
- default Optional getBasedir() {
- return getPomPath().map(Path::getParent);
+ Optional getBasedir();
+
+ /**
+ * Enforces presence of the project base directory and returns it.
+ */
+ @Nonnull
+ default Path requireBasedir() {
+ return getBasedir().orElseThrow(() -> new IllegalStateException("Project basedir not given"));
}
+ /**
+ * Returns the project direct dependencies (directly specified or inherited).
+ */
@Nonnull
List getDependencies();
+ /**
+ * Returns the project managed dependencies (directly specified or inherited).
+ */
@Nonnull
List getManagedDependencies();
+ /**
+ * Returns the project ID, usable as key.
+ */
@Nonnull
default String getId() {
return getModel().getId();
@@ -126,12 +205,21 @@ public interface Project {
@Nonnull
Path getRootDirectory();
+ /**
+ * Returns project parent project, if any.
+ */
@Nonnull
Optional getParent();
+ /**
+ * Returns immutable list of project remote repositories (directly specified or inherited).
+ */
@Nonnull
List getRemoteProjectRepositories();
+ /**
+ * Returns immutable list of project remote plugin repositories (directly specified or inherited).
+ */
@Nonnull
List getRemotePluginRepositories();
diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectManager.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectManager.java
index e31818a602..ec145090a6 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectManager.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectManager.java
@@ -40,17 +40,33 @@ import org.apache.maven.api.model.Resource;
@Experimental
public interface ProjectManager extends Service {
/**
- * Returns the path to the resolved file in the local repository
- * if the artifact has been resolved.
+ * Returns the path to the built project artifact file, if the project has been built.
*
- * @return the path of the resolved artifact
+ * @return the path of the built project artifact
*/
@Nonnull
Optional getPath(Project project);
+ /**
+ * Returns an immutable collection of attached artifacts for given project.
+ */
@Nonnull
Collection getAttachedArtifacts(Project project);
+ /**
+ * Returns project's all artifacts as immutable collection. The list contains all artifacts, even the attached ones,
+ * if any. Hence, the list returned by this method depends on which lifecycle step of the build was it invoked.
+ * The head of returned list is result of {@link Project#getArtifacts()} method, so same applies here: the list can have
+ * minimum of one element. The maximum number of elements is in turn dependent on build configuration and lifecycle
+ * phase when this method was invoked (i.e. is javadoc jar built and attached, is sources jar built attached, are
+ * all the artifact signed, etc.).
+ *
+ * This method is shorthand for {@link Project#getArtifacts()} and {@link #getAttachedArtifacts(Project)} methods.
+ *
+ * @see org.apache.maven.api.services.ArtifactManager#getPath(Artifact)
+ */
+ Collection getAllArtifacts(Project project);
+
default void attachArtifact(Session session, Project project, Path path) {
String name = path.getFileName().toString();
int dot = name.lastIndexOf('.');
diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java
index a2b00fb35a..3613eb1bb8 100644
--- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java
+++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java
@@ -28,9 +28,10 @@ import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.annotations.Nullable;
import org.apache.maven.api.model.DependencyManagement;
import org.apache.maven.api.model.Model;
-import org.apache.maven.api.services.ArtifactManager;
import org.apache.maven.api.services.TypeRegistry;
import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.artifact.ProjectArtifact;
+import org.eclipse.aether.util.artifact.ArtifactIdUtils;
public class DefaultProject implements Project {
@@ -70,13 +71,16 @@ public class DefaultProject implements Project {
@Nonnull
@Override
- public Artifact getArtifact() {
- org.eclipse.aether.artifact.Artifact resolverArtifact = RepositoryUtils.toArtifact(project.getArtifact());
- Artifact artifact = session.getArtifact(resolverArtifact);
- Path path =
- resolverArtifact.getFile() != null ? resolverArtifact.getFile().toPath() : null;
- session.getService(ArtifactManager.class).setPath(artifact, path);
- return artifact;
+ public List getArtifacts() {
+ org.eclipse.aether.artifact.Artifact pomArtifact = RepositoryUtils.toArtifact(new ProjectArtifact(project));
+ org.eclipse.aether.artifact.Artifact projectArtifact = RepositoryUtils.toArtifact(project.getArtifact());
+
+ ArrayList result = new ArrayList<>(2);
+ result.add(session.getArtifact(pomArtifact));
+ if (!ArtifactIdUtils.equalsVersionlessId(pomArtifact, projectArtifact)) {
+ result.add(session.getArtifact(projectArtifact));
+ }
+ return Collections.unmodifiableList(result);
}
@Nonnull
@@ -98,6 +102,15 @@ public class DefaultProject implements Project {
return Optional.ofNullable(file).map(File::toPath);
}
+ @Override
+ public Optional getBasedir() {
+ File basedir = project.getBasedir();
+ if (basedir == null) {
+ return Optional.empty();
+ }
+ return Optional.of(basedir.toPath());
+ }
+
@Nonnull
@Override
public List getDependencies() {
@@ -143,12 +156,14 @@ public class DefaultProject implements Project {
@Override
public List getRemoteProjectRepositories() {
- return new MappedList<>(project.getRemoteProjectRepositories(), session::getRemoteRepository);
+ return Collections.unmodifiableList(
+ new MappedList<>(project.getRemoteProjectRepositories(), session::getRemoteRepository));
}
@Override
public List getRemotePluginRepositories() {
- return new MappedList<>(project.getRemotePluginRepositories(), session::getRemoteRepository);
+ return Collections.unmodifiableList(
+ new MappedList<>(project.getRemotePluginRepositories(), session::getRemoteRepository));
}
@Override
diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java
index 1f0a22f7ae..560cb8be1a 100644
--- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java
+++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java
@@ -22,10 +22,7 @@ import javax.inject.Inject;
import javax.inject.Named;
import java.nio.file.Path;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
+import java.util.*;
import java.util.stream.Collectors;
import org.apache.maven.RepositoryUtils;
@@ -56,7 +53,11 @@ public class DefaultProjectManager implements ProjectManager {
@Nonnull
@Override
public Optional getPath(Project project) {
- return artifactManager.getPath(project.getArtifact());
+ Optional mainArtifact = project.getMainArtifact();
+ if (mainArtifact.isPresent()) {
+ return artifactManager.getPath(mainArtifact.get());
+ }
+ return Optional.empty();
}
@Nonnull
@@ -69,6 +70,14 @@ public class DefaultProjectManager implements ProjectManager {
return Collections.unmodifiableCollection(attached);
}
+ @Override
+ public Collection getAllArtifacts(Project project) {
+ ArrayList result = new ArrayList<>(2);
+ result.addAll(project.getArtifacts());
+ result.addAll(getAttachedArtifacts(project));
+ return Collections.unmodifiableCollection(result);
+ }
+
@Override
public void attachArtifact(Project project, Artifact artifact, Path path) {
getMavenProject(project)