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)