This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven.git

commit 6aa86c55b411666c9fbef94213fc2dc54438aa80
Author: Guillaume Nodet <gno...@gmail.com>
AuthorDate: Mon Feb 3 09:29:15 2025 +0100

    [MNG-8540] Replace ModelCache with the new cache API
---
 .../project/DefaultMavenProjectBuilderTest.java    |   8 -
 .../apache/maven/project/ProjectBuilderTest.java   |   8 -
 .../api/services/model/ModelCacheFactory.java      |  40 -----
 .../maven/impl/model/DefaultModelBuilder.java      | 171 +++++++++++++++++----
 .../apache/maven/impl/model/DefaultModelCache.java | 162 -------------------
 .../maven/impl/model/DefaultModelCacheFactory.java |  33 ----
 6 files changed, 145 insertions(+), 277 deletions(-)

diff --git 
a/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java
 
b/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java
index 0f06cf8019..60994b8213 100644
--- 
a/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java
+++ 
b/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java
@@ -25,8 +25,6 @@
 import java.nio.file.StandardCopyOption;
 import java.util.List;
 
-import org.apache.maven.api.SessionData;
-import org.apache.maven.api.services.model.ModelCache;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.impl.InternalSession;
@@ -338,12 +336,6 @@ void rereadPom_mng7063() throws Exception {
                 projectBuilder.build(pom.toFile(), 
buildingRequest).getProject();
         assertThat(project.getName(), is("aid")); // inherited from artifactId
 
-        // clear the cache
-        InternalSession.from(buildingRequest.getRepositorySession())
-                .getData()
-                .get(SessionData.key(ModelCache.class))
-                .clear();
-
         try (InputStream pomResource =
                 
DefaultMavenProjectBuilderTest.class.getResourceAsStream("/projects/reread/pom2.xml"))
 {
             Files.copy(pomResource, pom, StandardCopyOption.REPLACE_EXISTING);
diff --git 
a/impl/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java
 
b/impl/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java
index ef4eede284..9cdd456ad4 100644
--- 
a/impl/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java
+++ 
b/impl/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java
@@ -29,8 +29,6 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.maven.AbstractCoreMavenComponentTestCase;
-import org.apache.maven.api.SessionData;
-import org.apache.maven.api.services.model.ModelCache;
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.InputLocation;
@@ -179,12 +177,6 @@ void testReadModifiedPoms(@TempDir Path tempDir) throws 
Exception {
         File child = new File(tempDir.toFile(), "child/pom.xml");
         // build project once
         projectBuilder.build(child, configuration);
-        // clear the cache
-        mavenSession
-                .getSession()
-                .getData()
-                .get(SessionData.key(ModelCache.class))
-                .clear();
         // modify parent
         File parent = new File(tempDir.toFile(), "pom.xml");
         String parentContent = new String(Files.readAllBytes(parent.toPath()), 
StandardCharsets.UTF_8);
diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/api/services/model/ModelCacheFactory.java
 
b/impl/maven-impl/src/main/java/org/apache/maven/api/services/model/ModelCacheFactory.java
deleted file mode 100644
index 340121d21f..0000000000
--- 
a/impl/maven-impl/src/main/java/org/apache/maven/api/services/model/ModelCacheFactory.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.api.services.model;
-
-import org.apache.maven.api.annotations.Experimental;
-import org.apache.maven.api.annotations.Nonnull;
-
-/**
- * Factory for creating model caches.
- * <p>
- * The model cache is meant for exclusive consumption by the model builder and 
is opaque to the cache implementation.
- * The cache is created once per session and is valid through the lifetime of 
the session.
- * <p>
- * The cache implementation could be annotated with {@code SessionScoped} to 
be created once per session, but
- * this would make tests more complicated to write as they would all need to 
enter the session scope.
- *
- * @since 4.0.0
- */
-@Experimental
-public interface ModelCacheFactory {
-
-    @Nonnull
-    ModelCache newInstance();
-}
diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java
 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java
index 2809c0b19c..445f33cfcd 100644
--- 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java
+++ 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java
@@ -51,9 +51,12 @@
 import org.apache.maven.api.Constants;
 import org.apache.maven.api.RemoteRepository;
 import org.apache.maven.api.Session;
-import org.apache.maven.api.SessionData;
 import org.apache.maven.api.Type;
 import org.apache.maven.api.VersionRange;
+import org.apache.maven.api.annotations.Nonnull;
+import org.apache.maven.api.annotations.Nullable;
+import org.apache.maven.api.cache.CacheMetadata;
+import org.apache.maven.api.cache.CacheRetention;
 import org.apache.maven.api.di.Inject;
 import org.apache.maven.api.di.Named;
 import org.apache.maven.api.di.Singleton;
@@ -81,7 +84,9 @@
 import org.apache.maven.api.services.ModelSource;
 import org.apache.maven.api.services.ProblemCollector;
 import org.apache.maven.api.services.RepositoryFactory;
+import org.apache.maven.api.services.Request;
 import org.apache.maven.api.services.RequestTrace;
+import org.apache.maven.api.services.Result;
 import org.apache.maven.api.services.Source;
 import org.apache.maven.api.services.Sources;
 import org.apache.maven.api.services.SuperPomProvider;
@@ -89,8 +94,6 @@
 import org.apache.maven.api.services.model.DependencyManagementImporter;
 import org.apache.maven.api.services.model.DependencyManagementInjector;
 import org.apache.maven.api.services.model.InheritanceAssembler;
-import org.apache.maven.api.services.model.ModelCache;
-import org.apache.maven.api.services.model.ModelCacheFactory;
 import org.apache.maven.api.services.model.ModelInterpolator;
 import org.apache.maven.api.services.model.ModelNormalizer;
 import org.apache.maven.api.services.model.ModelPathTranslator;
@@ -151,7 +154,6 @@ public class DefaultModelBuilder implements ModelBuilder {
     private final PluginConfigurationExpander pluginConfigurationExpander;
     private final ModelVersionParser versionParser;
     private final List<ModelTransformer> transformers;
-    private final ModelCacheFactory modelCacheFactory;
     private final ModelResolver modelResolver;
     private final Interpolator interpolator;
     private final PathTranslator pathTranslator;
@@ -176,7 +178,6 @@ public DefaultModelBuilder(
             PluginConfigurationExpander pluginConfigurationExpander,
             ModelVersionParser versionParser,
             List<ModelTransformer> transformers,
-            ModelCacheFactory modelCacheFactory,
             ModelResolver modelResolver,
             Interpolator interpolator,
             PathTranslator pathTranslator,
@@ -197,7 +198,6 @@ public DefaultModelBuilder(
         this.pluginConfigurationExpander = pluginConfigurationExpander;
         this.versionParser = versionParser;
         this.transformers = transformers;
-        this.modelCacheFactory = modelCacheFactory;
         this.modelResolver = modelResolver;
         this.interpolator = interpolator;
         this.pathTranslator = pathTranslator;
@@ -253,7 +253,6 @@ protected class ModelBuilderSessionState implements 
ModelProblemCollector {
         final Session session;
         final ModelBuilderRequest request;
         final DefaultModelBuilderResult result;
-        final ModelCache cache;
         final Graph dag;
         final Map<GAKey, Set<ModelSource>> mappedSources;
 
@@ -270,9 +269,6 @@ protected class ModelBuilderSessionState implements 
ModelProblemCollector {
                     request.getSession(),
                     request,
                     new DefaultModelBuilderResult(request, 
ProblemCollector.create(request.getSession())),
-                    request.getSession()
-                            .getData()
-                            
.computeIfAbsent(SessionData.key(ModelCache.class), 
modelCacheFactory::newInstance),
                     new Graph(),
                     new ConcurrentHashMap<>(64),
                     List.of(),
@@ -292,7 +288,6 @@ private ModelBuilderSessionState(
                 Session session,
                 ModelBuilderRequest request,
                 DefaultModelBuilderResult result,
-                ModelCache cache,
                 Graph dag,
                 Map<GAKey, Set<ModelSource>> mappedSources,
                 List<RemoteRepository> pomRepositories,
@@ -301,7 +296,6 @@ private ModelBuilderSessionState(
             this.session = session;
             this.request = request;
             this.result = result;
-            this.cache = cache;
             this.dag = dag;
             this.mappedSources = mappedSources;
             this.pomRepositories = pomRepositories;
@@ -330,15 +324,7 @@ ModelBuilderSessionState derive(ModelBuilderRequest 
request, DefaultModelBuilder
                 throw new IllegalArgumentException("Session mismatch");
             }
             return new ModelBuilderSessionState(
-                    session,
-                    request,
-                    result,
-                    cache,
-                    dag,
-                    mappedSources,
-                    pomRepositories,
-                    externalRepositories,
-                    repositories);
+                    session, request, result, dag, mappedSources, 
pomRepositories, externalRepositories, repositories);
         }
 
         @Override
@@ -346,8 +332,7 @@ public String toString() {
             return "ModelBuilderSession[" + "session="
                     + session + ", " + "request="
                     + request + ", " + "result="
-                    + result + ", " + "cache="
-                    + cache + ']';
+                    + result + ']';
         }
 
         PhasingExecutor createExecutor() {
@@ -707,7 +692,6 @@ private void loadFromRoot(Path root, Path top) {
                                 + "build, the top project will be used as the 
root project.",
                         top,
                         root);
-                cache.clear();
                 mappedSources.clear();
                 loadFromRoot(top, top);
             }
@@ -1789,6 +1773,124 @@ ModelSource resolveReactorModel(String groupId, String 
artifactId, String versio
             return null;
         }
 
+        record RgavCacheKey(
+                Session session,
+                RequestTrace trace,
+                List<RemoteRepository> repositories,
+                String groupId,
+                String artifactId,
+                String version,
+                String classifier,
+                String tag)
+                implements Request<Session> {
+            @Nonnull
+            @Override
+            public Session getSession() {
+                return session;
+            }
+
+            @Nullable
+            @Override
+            public RequestTrace getTrace() {
+                return trace;
+            }
+
+            @Override
+            public boolean equals(Object o) {
+                return o instanceof RgavCacheKey that
+                        && Objects.equals(tag, that.tag)
+                        && Objects.equals(groupId, that.groupId)
+                        && Objects.equals(version, that.version)
+                        && Objects.equals(artifactId, that.artifactId)
+                        && Objects.equals(classifier, that.classifier)
+                        && Objects.equals(repositories, that.repositories);
+            }
+
+            @Override
+            public int hashCode() {
+                return Objects.hash(repositories, groupId, artifactId, 
version, classifier, tag);
+            }
+
+            @Override
+            public String toString() {
+                StringBuilder sb = new StringBuilder();
+                
sb.append(getClass().getSimpleName()).append("[").append("gav='");
+                if (groupId != null) {
+                    sb.append(groupId);
+                }
+                sb.append(":");
+                if (artifactId != null) {
+                    sb.append(artifactId);
+                }
+                sb.append(":");
+                if (version != null) {
+                    sb.append(version);
+                }
+                sb.append(":");
+                if (classifier != null) {
+                    sb.append(classifier);
+                }
+                sb.append("', tag='");
+                sb.append(tag);
+                sb.append("']");
+                return sb.toString();
+            }
+        }
+
+        record SourceCacheKey(Session session, RequestTrace trace, Source 
source, String tag)
+                implements Request<Session>, CacheMetadata {
+            @Nonnull
+            @Override
+            public Session getSession() {
+                return session;
+            }
+
+            @Nullable
+            @Override
+            public RequestTrace getTrace() {
+                return trace;
+            }
+
+            @Override
+            public CacheRetention getCacheRetention() {
+                return source instanceof CacheMetadata cacheMetadata ? 
cacheMetadata.getCacheRetention() : null;
+            }
+
+            @Override
+            public boolean equals(Object o) {
+                return o instanceof SourceCacheKey that
+                        && Objects.equals(tag, that.tag)
+                        && Objects.equals(source, that.source);
+            }
+
+            @Override
+            public int hashCode() {
+                return Objects.hash(source, tag);
+            }
+
+            @Override
+            public String toString() {
+                return getClass().getSimpleName() + "[" + "location=" + 
source.getLocation() + ", tag=" + tag
+                        + ", path=" + source.getPath() + ']';
+            }
+        }
+
+        static class SourceResponse<R extends Request<?>, T> implements 
Result<R> {
+            private final R request;
+            private final T response;
+
+            SourceResponse(R request, T response) {
+                this.request = request;
+                this.response = response;
+            }
+
+            @Nonnull
+            @Override
+            public R getRequest() {
+                return request;
+            }
+        }
+
         private <T> T cache(
                 List<RemoteRepository> repositories,
                 String groupId,
@@ -1797,11 +1899,28 @@ private <T> T cache(
                 String classifier,
                 String tag,
                 Supplier<T> supplier) {
-            return cache.computeIfAbsent(repositories, groupId, artifactId, 
version, classifier, tag, supplier);
+            RequestTraceHelper.ResolverTrace trace = 
RequestTraceHelper.enter(session, request);
+            try {
+                RgavCacheKey r = new RgavCacheKey(
+                        session, trace.mvnTrace(), repositories, groupId, 
artifactId, version, classifier, tag);
+                SourceResponse<RgavCacheKey, T> response =
+                        InternalSession.from(session).request(r, tr -> new 
SourceResponse<>(tr, supplier.get()));
+                return response.response;
+            } finally {
+                RequestTraceHelper.exit(trace);
+            }
         }
 
         private <T> T cache(Source source, String tag, Supplier<T> supplier) 
throws ModelBuilderException {
-            return cache.computeIfAbsent(source, tag, supplier);
+            RequestTraceHelper.ResolverTrace trace = 
RequestTraceHelper.enter(session, request);
+            try {
+                SourceCacheKey r = new SourceCacheKey(session, 
trace.mvnTrace(), source, tag);
+                SourceResponse<SourceCacheKey, T> response =
+                        InternalSession.from(session).request(r, tr -> new 
SourceResponse<>(tr, supplier.get()));
+                return response.response;
+            } finally {
+                RequestTraceHelper.exit(trace);
+            }
         }
 
         boolean isBuildRequest() {
diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelCache.java
 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelCache.java
deleted file mode 100644
index 8c6cc1bb92..0000000000
--- 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelCache.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.impl.model;
-
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.function.Supplier;
-
-import org.apache.maven.api.RemoteRepository;
-import org.apache.maven.api.services.Source;
-import org.apache.maven.api.services.model.ModelCache;
-
-import static java.util.Objects.requireNonNull;
-
-/**
- * A model builder cache backed by the repository system cache.
- *
- */
-public class DefaultModelCache implements ModelCache {
-
-    private final ConcurrentMap<Object, Supplier<?>> cache;
-
-    public DefaultModelCache() {
-        this(new ConcurrentHashMap<>());
-    }
-
-    private DefaultModelCache(ConcurrentMap<Object, Supplier<?>> cache) {
-        this.cache = requireNonNull(cache);
-    }
-
-    @Override
-    @SuppressWarnings({"unchecked"})
-    public <T> T computeIfAbsent(
-            List<RemoteRepository> repositories,
-            String groupId,
-            String artifactId,
-            String version,
-            String classifier,
-            String tag,
-            Supplier<T> data) {
-        return (T) computeIfAbsent(new RgavCacheKey(repositories, groupId, 
artifactId, version, classifier, tag), data);
-    }
-
-    @Override
-    @SuppressWarnings({"unchecked"})
-    public <T> T computeIfAbsent(Source path, String tag, Supplier<T> data) {
-        return (T) computeIfAbsent(new SourceCacheKey(path, tag), data);
-    }
-
-    @Override
-    public void clear() {
-        cache.clear();
-    }
-
-    protected Object computeIfAbsent(Object key, Supplier<?> data) {
-        return cache.computeIfAbsent(key, k -> new 
CachingSupplier<>(data)).get();
-    }
-
-    record RgavCacheKey(
-            List<RemoteRepository> repositories,
-            String groupId,
-            String artifactId,
-            String version,
-            String classifier,
-            String tag) {
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            sb.append(getClass().getSimpleName()).append("[").append("gav='");
-            if (groupId != null) {
-                sb.append(groupId);
-            }
-            sb.append(":");
-            if (artifactId != null) {
-                sb.append(artifactId);
-            }
-            sb.append(":");
-            if (version != null) {
-                sb.append(version);
-            }
-            sb.append(":");
-            if (classifier != null) {
-                sb.append(classifier);
-            }
-            sb.append("', tag='");
-            sb.append(tag);
-            sb.append("']");
-            return sb.toString();
-        }
-    }
-
-    record SourceCacheKey(Source source, String tag) {
-
-        @Override
-        public String toString() {
-            return getClass().getSimpleName() + "[" + "location=" + 
source.getLocation() + ", tag=" + tag + ", path="
-                    + source.getPath() + ']';
-        }
-    }
-
-    static class CachingSupplier<T> implements Supplier<T> {
-        Supplier<T> supplier;
-        volatile Object value;
-
-        CachingSupplier(Supplier<T> supplier) {
-            this.supplier = supplier;
-        }
-
-        @Override
-        @SuppressWarnings({"unchecked", "checkstyle:InnerAssignment"})
-        public T get() {
-            Object v;
-            if ((v = value) == null) {
-                synchronized (this) {
-                    if ((v = value) == null) {
-                        try {
-                            v = value = supplier.get();
-                            supplier = null;
-                        } catch (Exception e) {
-                            v = value = new AltRes(e);
-                        }
-                    }
-                }
-            }
-            if (v instanceof AltRes altRes) {
-                uncheckedThrow(altRes.t);
-            }
-            return (T) v;
-        }
-
-        static class AltRes {
-            final Throwable t;
-
-            AltRes(Throwable t) {
-                this.t = t;
-            }
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    static <T extends Throwable> void uncheckedThrow(Throwable t) throws T {
-        throw (T) t; // rely on vacuous cast
-    }
-}
diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelCacheFactory.java
 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelCacheFactory.java
deleted file mode 100644
index ad567d934d..0000000000
--- 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelCacheFactory.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.impl.model;
-
-import org.apache.maven.api.di.Named;
-import org.apache.maven.api.di.Singleton;
-import org.apache.maven.api.services.model.ModelCache;
-import org.apache.maven.api.services.model.ModelCacheFactory;
-
-@Named
-@Singleton
-public class DefaultModelCacheFactory implements ModelCacheFactory {
-    @Override
-    public ModelCache newInstance() {
-        return new DefaultModelCache();
-    }
-}

Reply via email to