Skip to content

Commit

Permalink
Use SessionData to store ProjectIndex (#1423)
Browse files Browse the repository at this point in the history
  • Loading branch information
gnodet committed Feb 28, 2024
1 parent 3c2f8eb commit 5307bcb
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package org.apache.maven.api;

import java.util.Objects;
import java.util.function.Supplier;

import org.apache.maven.api.annotations.Experimental;
Expand Down Expand Up @@ -49,7 +50,7 @@ public interface SessionData {
* @param key the key under which to store the session data, must not be {@code null}
* @param value the data to associate with the key, may be {@code null} to remove the mapping
*/
void set(@Nonnull Object key, @Nullable Object value);
<T> void set(@Nonnull Key<T> key, @Nullable T value);

/**
* Associates the specified session data with the given key if the key is currently mapped to the given value. This
Expand All @@ -61,7 +62,7 @@ public interface SessionData {
* @return {@code true} if the key mapping was successfully updated from the old value to the new value,
* {@code false} if the current key mapping didn't match the expected value and was not updated.
*/
boolean set(@Nonnull Object key, @Nullable Object oldValue, @Nullable Object newValue);
<T> boolean replace(@Nonnull Key<T> key, @Nullable T oldValue, @Nullable T newValue);

/**
* Gets the session data associated with the specified key.
Expand All @@ -70,7 +71,7 @@ public interface SessionData {
* @return the session data associated with the key or {@code null} if none
*/
@Nullable
Object get(@Nonnull Object key);
<T> T get(@Nonnull Key<T> key);

/**
* Retrieve of compute the data associated with the specified key.
Expand All @@ -80,5 +81,55 @@ public interface SessionData {
* @return the session data associated with the key
*/
@Nullable
Object computeIfAbsent(@Nonnull Object key, @Nonnull Supplier<Object> supplier);
<T> T computeIfAbsent(@Nonnull Key<T> key, @Nonnull Supplier<T> supplier);

/**
* Create a key using the given class as an identifier and as the type of the object.
*/
static <T> Key<T> key(Class<T> clazz) {
return new Key<>(clazz, clazz);
}

/**
* Create a key using the given class and id.
*/
static <T> Key<T> key(Class<T> clazz, Object id) {
return new Key<>(clazz, id);
}

/**
* Key used to query the session data
* @param <T> the type of the object associated to this key
*/
final class Key<T> {

private final Class<T> type;
private final Object id;

private Key(Class<T> type, Object id) {
this.type = type;
this.id = id;
}

public Class<T> type() {
return type;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Key<?> key = (Key<?>) o;
return Objects.equals(id, key.id) && Objects.equals(type, key.type);
}

@Override
public int hashCode() {
return Objects.hash(id, type);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -177,25 +177,27 @@ public SessionData getData() {
org.eclipse.aether.SessionData data = session.getData();
return new SessionData() {
@Override
public void set(@Nonnull Object key, @Nullable Object value) {
public <T> void set(@Nonnull Key<T> key, @Nullable T value) {
data.set(key, value);
}

@Override
public boolean set(@Nonnull Object key, @Nullable Object oldValue, @Nullable Object newValue) {
public <T> boolean replace(@Nonnull Key<T> key, @Nullable T oldValue, @Nullable T newValue) {
return data.set(key, oldValue, newValue);
}

@Nullable
@Override
public Object get(@Nonnull Object key) {
return data.get(key);
@SuppressWarnings("unchecked")
public <T> T get(@Nonnull Key<T> key) {
return (T) data.get(key);
}

@Nullable
@Override
public Object computeIfAbsent(@Nonnull Object key, @Nonnull Supplier<Object> supplier) {
return data.computeIfAbsent(key, supplier);
@SuppressWarnings("unchecked")
public <T> T computeIfAbsent(@Nonnull Key<T> key, @Nonnull Supplier<T> supplier) {
return (T) data.computeIfAbsent(key, (Supplier<Object>) supplier);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import org.apache.maven.lifecycle.internal.LifecycleStarter;
import org.apache.maven.lifecycle.internal.LifecycleTaskSegmentCalculator;
import org.apache.maven.lifecycle.internal.MojoExecutor;
import org.apache.maven.lifecycle.internal.ProjectIndex;
import org.apache.maven.lifecycle.internal.TaskSegment;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.InvalidPluginDescriptorException;
Expand Down Expand Up @@ -146,6 +145,6 @@ public void calculateForkedExecutions(MojoExecution mojoExecution, MavenSession
// Site 3.x
public List<MavenProject> executeForkedExecutions(MojoExecution mojoExecution, MavenSession session)
throws LifecycleExecutionException {
return mojoExecutor.executeForkedExecutions(mojoExecution, session, new ProjectIndex(session.getProjects()));
return mojoExecutor.executeForkedExecutions(mojoExecution, session);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public void buildProject(

projectExecutionListener.beforeProjectLifecycleExecution(
new ProjectExecutionEvent(session, currentProject, mojoExecutions));
mojoExecutor.execute(session, mojoExecutions, reactorContext.getProjectIndex());
mojoExecutor.execute(session, mojoExecutions);

long buildEndTime = System.currentTimeMillis();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public void execute(MavenSession session) {

ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
ReactorBuildStatus reactorBuildStatus = new ReactorBuildStatus(session.getProjectDependencyGraph());
reactorContext = new ReactorContext(result, projectIndex, oldContextClassLoader, reactorBuildStatus);
reactorContext = new ReactorContext(result, oldContextClassLoader, reactorBuildStatus);

String builderId = session.getRequest().getBuilderId();
Builder builder = builders.get(builderId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.maven.api.SessionData;
import org.apache.maven.api.services.MessageBuilderFactory;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
Expand All @@ -57,7 +58,6 @@
import org.apache.maven.plugin.PluginManagerException;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.SessionData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -74,6 +74,11 @@
public class MojoExecutor {

private static final Logger LOGGER = LoggerFactory.getLogger(MojoExecutor.class);
private static final SessionData.Key<ProjectIndex> PROJECT_INDEX = SessionData.key(ProjectIndex.class);

@SuppressWarnings({"unchecked", "rawtypes"})
private static final SessionData.Key<Map<MavenProject, OwnerReentrantLock>> PROJECT_LOCKS =
(SessionData.Key) SessionData.key(Map.class, ProjectLock.class);

private final BuildPluginManager pluginManager;
private final MavenPluginManager mavenPluginManager;
Expand Down Expand Up @@ -149,8 +154,7 @@ private Collection<String> toScopes(String classpath) {
return Collections.unmodifiableCollection(scopes);
}

public void execute(
final MavenSession session, final List<MojoExecution> mojoExecutions, final ProjectIndex projectIndex)
public void execute(final MavenSession session, final List<MojoExecution> mojoExecutions)
throws LifecycleExecutionException {

final DependencyContext dependencyContext = newDependencyContext(session, mojoExecutions);
Expand All @@ -160,27 +164,22 @@ public void execute(
mojosExecutionStrategy.get().execute(mojoExecutions, session, new MojoExecutionRunner() {
@Override
public void run(MojoExecution mojoExecution) throws LifecycleExecutionException {
MojoExecutor.this.execute(session, mojoExecution, projectIndex, dependencyContext, phaseRecorder);
MojoExecutor.this.execute(session, mojoExecution, dependencyContext, phaseRecorder);
}
});
}

private void execute(
MavenSession session,
MojoExecution mojoExecution,
ProjectIndex projectIndex,
DependencyContext dependencyContext,
PhaseRecorder phaseRecorder)
throws LifecycleExecutionException {
execute(session, mojoExecution, projectIndex, dependencyContext);
execute(session, mojoExecution, dependencyContext);
phaseRecorder.observeExecution(mojoExecution);
}

private void execute(
MavenSession session,
MojoExecution mojoExecution,
ProjectIndex projectIndex,
DependencyContext dependencyContext)
private void execute(MavenSession session, MojoExecution mojoExecution, DependencyContext dependencyContext)
throws LifecycleExecutionException {
MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();

Expand Down Expand Up @@ -211,7 +210,7 @@ private void execute(
}
}

doExecute(session, mojoExecution, projectIndex, dependencyContext);
doExecute(session, mojoExecution, dependencyContext);
}

/**
Expand Down Expand Up @@ -273,11 +272,9 @@ public void close() {
mojos.remove(Thread.currentThread());
}

@SuppressWarnings({"unchecked", "rawtypes"})
private OwnerReentrantLock getProjectLock(MavenSession session) {
SessionData data = session.getRepositorySession().getData();
Map<MavenProject, OwnerReentrantLock> locks =
(Map) data.computeIfAbsent(ProjectLock.class, ConcurrentHashMap::new);
SessionData data = session.getSession().getData();
Map<MavenProject, OwnerReentrantLock> locks = data.computeIfAbsent(PROJECT_LOCKS, ConcurrentHashMap::new);
return locks.computeIfAbsent(session.getCurrentProject(), p -> new OwnerReentrantLock());
}
}
Expand All @@ -302,15 +299,11 @@ private static void warn(String msg) {
}
}

private void doExecute(
MavenSession session,
MojoExecution mojoExecution,
ProjectIndex projectIndex,
DependencyContext dependencyContext)
private void doExecute(MavenSession session, MojoExecution mojoExecution, DependencyContext dependencyContext)
throws LifecycleExecutionException {
MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();

List<MavenProject> forkedProjects = executeForkedExecutions(mojoExecution, session, projectIndex);
List<MavenProject> forkedProjects = executeForkedExecutions(mojoExecution, session);

ensureDependenciesAreResolved(mojoDescriptor, session, dependencyContext);

Expand Down Expand Up @@ -407,8 +400,7 @@ private ArtifactFilter getArtifactFilter(MojoDescriptor mojoDescriptor) {
}
}

public List<MavenProject> executeForkedExecutions(
MojoExecution mojoExecution, MavenSession session, ProjectIndex projectIndex)
public List<MavenProject> executeForkedExecutions(MojoExecution mojoExecution, MavenSession session)
throws LifecycleExecutionException {
List<MavenProject> forkedProjects = Collections.emptyList();

Expand All @@ -425,6 +417,10 @@ public List<MavenProject> executeForkedExecutions(
for (Map.Entry<String, List<MojoExecution>> fork : forkedExecutions.entrySet()) {
String projectId = fork.getKey();

ProjectIndex projectIndex = session.getSession()
.getData()
.computeIfAbsent(PROJECT_INDEX, () -> new ProjectIndex(session.getProjects()));

int index = projectIndex.getIndices().get(projectId);

MavenProject forkedProject = projectIndex.getProjects().get(projectId);
Expand All @@ -448,7 +444,7 @@ public List<MavenProject> executeForkedExecutions(

eventCatapult.fire(ExecutionEvent.Type.ForkedProjectStarted, session, mojoExecution);

execute(session, mojoExecutions, projectIndex);
execute(session, mojoExecutions);

eventCatapult.fire(ExecutionEvent.Type.ForkedProjectSucceeded, session, mojoExecution);
} catch (LifecycleExecutionException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,15 @@
public class ReactorContext {
private final MavenExecutionResult result;

private final ProjectIndex projectIndex;

private final ClassLoader originalContextClassLoader;

private final ReactorBuildStatus reactorBuildStatus;

public ReactorContext(
MavenExecutionResult result,
ProjectIndex projectIndex,
ClassLoader originalContextClassLoader,
ReactorBuildStatus reactorBuildStatus) {
this.result = result;
this.projectIndex = projectIndex;
this.originalContextClassLoader = originalContextClassLoader;
this.reactorBuildStatus = reactorBuildStatus;
}
Expand All @@ -54,10 +50,6 @@ public MavenExecutionResult getResult() {
return result;
}

public ProjectIndex getProjectIndex() {
return projectIndex;
}

public ClassLoader getOriginalContextClassLoader() {
return originalContextClassLoader;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ void testCurrentProject() throws Exception {
List<MavenProject> currentProjects = new ArrayList<>();
MojoExecutorStub mojoExecutor = new MojoExecutorStub() {
@Override
public void execute(MavenSession session, List<MojoExecution> mojoExecutions, ProjectIndex projectIndex)
public void execute(MavenSession session, List<MojoExecution> mojoExecutions)
throws LifecycleExecutionException {
super.execute(session, mojoExecutions, projectIndex);
super.execute(session, mojoExecutions);
currentProjects.add(session.getCurrentProject());
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import org.apache.maven.lifecycle.internal.ExecutionEventCatapult;
import org.apache.maven.lifecycle.internal.LifecycleDependencyResolver;
import org.apache.maven.lifecycle.internal.MojoExecutor;
import org.apache.maven.lifecycle.internal.ProjectIndex;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.BuildPluginManager;
import org.apache.maven.plugin.MavenPluginManager;
Expand Down Expand Up @@ -67,14 +66,12 @@ public MojoExecutorStub(
}

@Override
public void execute(MavenSession session, List<MojoExecution> mojoExecutions, ProjectIndex projectIndex)
throws LifecycleExecutionException {
public void execute(MavenSession session, List<MojoExecution> mojoExecutions) throws LifecycleExecutionException {
executions.addAll(mojoExecutions);
}

@Override
public List<MavenProject> executeForkedExecutions(
MojoExecution mojoExecution, MavenSession session, ProjectIndex projectIndex)
public List<MavenProject> executeForkedExecutions(MojoExecution mojoExecution, MavenSession session)
throws LifecycleExecutionException {
return null;
}
Expand Down

0 comments on commit 5307bcb

Please sign in to comment.