Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MNG-8037] Restrict project to the entity being built and make it immutable #1389

Merged
merged 3 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
75 changes: 32 additions & 43 deletions api/maven-api-core/src/main/java/org/apache/maven/api/Project.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.apache.maven.api.annotations.Experimental;
Expand All @@ -29,10 +28,24 @@
import org.apache.maven.api.model.Model;

/**
* Interface representing a Maven project.
* Projects can be built using the {@link org.apache.maven.api.services.ProjectBuilder} service.
* Interface representing a Maven project which can be created using the
* {@link org.apache.maven.api.services.ProjectBuilder} service.
* Such objects are immutable and plugin that wish to modify such objects
* need to do so using the {@link org.apache.maven.api.services.ProjectManager}
* service.
* <p>
* Projects are created using the {@code ProjectBuilder} either from a POM file
* (usually named {@code pom.xml}) on the file system or by loading the POM
* associated to an artifact coordinate in a repository. In the first case,
* the {@link #getPomPath()} will point to the POM file and the
* {@link #getBasedir()} to the directory parent containing the
* POM file. If the project is loaded from a repository, both these values
* will be {@link Optional#empty()}.
* </p>
*
* @since 4.0.0
* @see org.apache.maven.api.services.ProjectManager
* @see org.apache.maven.api.services.ProjectBuilder
*/
@Experimental
public interface Project {
Expand Down Expand Up @@ -124,27 +137,29 @@ default Build getBuild() {

/**
* Returns the path to the pom file for this project.
* A project is usually read from the file system and this will point to
* the file. In some cases, a transient project can be created which
* will not point to an actual pom file.
* A project is usually read from a file named {@code pom.xml},
* which contains the {@linkplain #getModel() model} in an XML form.
* When a custom {@code org.apache.maven.api.spi.ModelParser} is used,
* the path may point to a non XML file.
* <p>
* The POM path is also used to define the {@linkplain #getBasedir() base directory}
* of the project.
*
* @return the path of the pom
* @see #getBasedir()
*/
@Nonnull
Optional<Path> getPomPath();

/**
* Returns the project base directory.
*/
@Nonnull
Optional<Path> getBasedir();
Path getPomPath();

/**
* Enforces presence of the project base directory and returns it.
* Returns the project base directory, i.e. the directory containing the project.
* A project is usually read from the file system and this will point to
* the directory containing the POM file.
*
* @return the path of the directory containing the project
*/
@Nonnull
default Path requireBasedir() {
return getBasedir().orElseThrow(() -> new IllegalStateException("Project basedir not given"));
}
Path getBasedir();

/**
* Returns the project direct dependencies (directly specified or inherited).
Expand All @@ -166,12 +181,6 @@ default String getId() {
return getModel().getId();
}

/**
* @deprecated use {@link #isTopProject()} instead
*/
@Deprecated
boolean isExecutionRoot();

/**
* Returns a boolean indicating if the project is the top level project for
* this reactor build. The top level project may be different from the
Expand Down Expand Up @@ -210,24 +219,4 @@ default String getId() {
*/
@Nonnull
Optional<Project> getParent();

/**
* Returns immutable list of project remote repositories (directly specified or inherited).
*/
@Nonnull
List<RemoteRepository> getRemoteProjectRepositories();

/**
* Returns immutable list of project remote plugin repositories (directly specified or inherited).
*/
@Nonnull
List<RemoteRepository> getRemotePluginRepositories();

/**
* Returns the project properties as immutable map.
*
* @see org.apache.maven.api.services.ProjectManager#setProperty(Project, String, String)
*/
@Nonnull
Map<String, String> getProperties();
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@

import java.nio.file.Path;

import org.apache.maven.api.Artifact;
import org.apache.maven.api.ArtifactCoordinate;
import org.apache.maven.api.Service;
import org.apache.maven.api.Session;
import org.apache.maven.api.annotations.Experimental;
Expand Down Expand Up @@ -71,32 +69,4 @@ default ProjectBuilderResult build(@Nonnull Session session, @Nonnull Source sou
default ProjectBuilderResult build(@Nonnull Session session, @Nonnull Path path) {
return build(ProjectBuilderRequest.build(session, path));
}

/**
* Creates a {@link org.apache.maven.api.Project} from an artifact.
*
* @param session the {@link Session}, must not be {@code null}
* @param artifact the {@link Artifact}, must not be {@code null}
* @throws ProjectBuilderException if the project cannot be created
* @throws IllegalArgumentException if an argument is {@code null} or invalid
* @see #build(ProjectBuilderRequest)
*/
@Nonnull
default ProjectBuilderResult build(@Nonnull Session session, @Nonnull Artifact artifact) {
return build(ProjectBuilderRequest.build(session, artifact));
}

/**
* Creates a {@link org.apache.maven.api.Project} from a coordinate.
*
* @param session the {@link Session}, must not be {@code null}
* @param coordinate the {@link ArtifactCoordinate}, must not be {@code null}
* @throws ProjectBuilderException if the project cannot be created
* @throws IllegalArgumentException if an argument is {@code null} or invalid
* @see #build(ProjectBuilderRequest)
*/
@Nonnull
default ProjectBuilderResult build(@Nonnull Session session, @Nonnull ArtifactCoordinate coordinate) {
return build(ProjectBuilderRequest.build(session, coordinate));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import java.nio.file.Path;
import java.util.Optional;

import org.apache.maven.api.Artifact;
import org.apache.maven.api.ArtifactCoordinate;
import org.apache.maven.api.Session;
import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Immutable;
Expand All @@ -36,6 +34,8 @@
* Request used to build a {@link org.apache.maven.api.Project} using
* the {@link ProjectBuilder} service.
*
* TODO: add validationLevel, activeProfileIds, inactiveProfileIds, resolveDependencies
*
* @since 4.0.0
*/
@Experimental
Expand All @@ -51,20 +51,12 @@ public interface ProjectBuilderRequest {
@Nonnull
Optional<Source> getSource();

@Nonnull
Optional<Artifact> getArtifact();

@Nonnull
Optional<ArtifactCoordinate> getCoordinate();

boolean isAllowStubModel();

boolean isRecursive();

boolean isProcessPlugins();

boolean isResolveDependencies();

@Nonnull
static ProjectBuilderRequest build(@Nonnull Session session, @Nonnull Source source) {
return builder()
Expand All @@ -81,22 +73,6 @@ static ProjectBuilderRequest build(@Nonnull Session session, @Nonnull Path path)
.build();
}

@Nonnull
static ProjectBuilderRequest build(@Nonnull Session session, @Nonnull Artifact artifact) {
return builder()
.session(nonNull(session, "session cannot be null"))
.artifact(nonNull(artifact, "artifact cannot be null"))
.build();
}

@Nonnull
static ProjectBuilderRequest build(@Nonnull Session session, @Nonnull ArtifactCoordinate coordinate) {
return builder()
.session(nonNull(session, "session cannot be null"))
.coordinate(nonNull(coordinate, "coordinate cannot be null"))
.build();
}

@Nonnull
static ProjectBuilderRequestBuilder builder() {
return new ProjectBuilderRequestBuilder();
Expand All @@ -107,12 +83,9 @@ class ProjectBuilderRequestBuilder {
Session session;
Path path;
Source source;
Artifact artifact;
ArtifactCoordinate coordinate;
boolean allowStubModel;
boolean recursive;
boolean processPlugins = true;
boolean resolveDependencies = true;

ProjectBuilderRequestBuilder() {}

Expand All @@ -131,69 +104,36 @@ public ProjectBuilderRequestBuilder source(Source source) {
return this;
}

public ProjectBuilderRequestBuilder artifact(Artifact artifact) {
this.artifact = artifact;
return this;
}

public ProjectBuilderRequestBuilder coordinate(ArtifactCoordinate coordinate) {
this.coordinate = coordinate;
return this;
}

public ProjectBuilderRequestBuilder processPlugins(boolean processPlugins) {
this.processPlugins = processPlugins;
return this;
}

public ProjectBuilderRequestBuilder resolveDependencies(boolean resolveDependencies) {
this.resolveDependencies = resolveDependencies;
return this;
}

public ProjectBuilderRequest build() {
return new DefaultProjectBuilderRequest(
session,
path,
source,
artifact,
coordinate,
allowStubModel,
recursive,
processPlugins,
resolveDependencies);
return new DefaultProjectBuilderRequest(session, path, source, allowStubModel, recursive, processPlugins);
}

private static class DefaultProjectBuilderRequest extends BaseRequest implements ProjectBuilderRequest {
private final Path path;
private final Source source;
private final Artifact artifact;
private final ArtifactCoordinate coordinate;
private final boolean allowStubModel;
private final boolean recursive;
private final boolean processPlugins;
private final boolean resolveDependencies;

@SuppressWarnings("checkstyle:ParameterNumber")
DefaultProjectBuilderRequest(
@Nonnull Session session,
@Nullable Path path,
@Nullable Source source,
@Nullable Artifact artifact,
@Nullable ArtifactCoordinate coordinate,
boolean allowStubModel,
boolean recursive,
boolean processPlugins,
boolean resolveDependencies) {
boolean processPlugins) {
super(session);
this.path = path;
this.source = source;
this.artifact = artifact;
this.coordinate = coordinate;
this.allowStubModel = allowStubModel;
this.recursive = recursive;
this.processPlugins = processPlugins;
this.resolveDependencies = resolveDependencies;
}

@Nonnull
Expand All @@ -208,18 +148,6 @@ public Optional<Source> getSource() {
return Optional.ofNullable(source);
}

@Nonnull
@Override
public Optional<Artifact> getArtifact() {
return Optional.ofNullable(artifact);
}

@Nonnull
@Override
public Optional<ArtifactCoordinate> getCoordinate() {
return Optional.ofNullable(coordinate);
}

@Override
public boolean isAllowStubModel() {
return allowStubModel;
Expand All @@ -234,11 +162,6 @@ public boolean isRecursive() {
public boolean isProcessPlugins() {
return processPlugins;
}

@Override
public boolean isResolveDependencies() {
return resolveDependencies;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.apache.maven.api.Artifact;
Expand All @@ -30,6 +31,7 @@
import org.apache.maven.api.Session;
import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.annotations.Nullable;
import org.apache.maven.api.model.Resource;

/**
Expand Down Expand Up @@ -100,9 +102,38 @@ default void attachArtifact(Session session, Project project, String type, Path

void addTestResource(Project project, Resource resource);

List<RemoteRepository> getRepositories(Project project);
/**
* Returns an immutable list of project remote repositories (directly specified or inherited).
*
* @param project the project
*/
@Nonnull
List<RemoteRepository> getRemoteProjectRepositories(@Nonnull Project project);

/**
* Returns an immutable list of project remote plugin repositories (directly specified or inherited).
*
* @param project the project
*/
@Nonnull
List<RemoteRepository> getRemotePluginRepositories(@Nonnull Project project);

void setProperty(Project project, String key, String value);
/**
* Returns an immutable map of the project properties.
*
* @see #setProperty(Project, String, String)
*/
@Nonnull
Map<String, String> getProperties(@Nonnull Project project);

/**
* Set a given project property.
*
* @param project the project to modify
* @param key they property's key
* @param value the value or {@code null} to unset the property
*/
void setProperty(@Nonnull Project project, @Nonnull String key, @Nullable String value);

@Nonnull
Optional<Project> getExecutionProject(@Nonnull Project project);
Expand Down