diff --git a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/model/DefaultModelBuilder.java b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/model/DefaultModelBuilder.java index a5ea27ec39bb..26ae7f67ea89 100644 --- a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/model/DefaultModelBuilder.java +++ b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/model/DefaultModelBuilder.java @@ -25,7 +25,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.EnumSet; import java.util.HashMap; @@ -233,14 +232,15 @@ protected final class DefaultModelBuilderSession implements ModelProblemCollecto final DefaultModelBuilderResult result; final ModelCache cache; final Graph dag; - final Map modelByPath; - final Map modelByGA; final Map> mappedSources; - final RepositoryHolder repositoryHolder; - private String source; - private Model sourceModel; - private Model rootModel; + String source; + Model sourceModel; + Model rootModel; + + List pomRepositories; + List externalRepositories; + List repositories; private Set severities = EnumSet.noneOf(ModelProblem.Severity.class); @@ -265,16 +265,7 @@ protected final class DefaultModelBuilderSession implements ModelProblemCollecto DefaultModelBuilderSession( Session session, ModelBuilderRequest request, DefaultModelBuilderResult result, ModelCache cache) { - this( - session, - request, - result, - cache, - new Graph(), - new ConcurrentHashMap<>(64), - new ConcurrentHashMap<>(64), - new ConcurrentHashMap<>(64), - null); + this(session, request, result, cache, new Graph(), new ConcurrentHashMap<>(64), null, null, null); } @SuppressWarnings("checkstyle:ParameterNumber") @@ -284,24 +275,28 @@ private DefaultModelBuilderSession( DefaultModelBuilderResult result, ModelCache cache, Graph dag, - Map modelByPath, - Map modelByGA, Map> mappedSources, - RepositoryHolder repositoryHolder) { + List pomRepositories, + List externalRepositories, + List repositories) { this.session = session; this.request = request; this.result = result; this.cache = cache; this.dag = dag; - this.modelByPath = modelByPath; - this.modelByGA = modelByGA; this.mappedSources = mappedSources; - this.repositoryHolder = repositoryHolder != null - ? repositoryHolder - : new RepositoryHolder( - request.getRepositories() != null - ? request.getRepositories() - : session.getRemoteRepositories()); + if (pomRepositories == null) { + this.pomRepositories = List.of(); + this.externalRepositories = List.copyOf( + request.getRepositories() != null + ? request.getRepositories() + : session.getRemoteRepositories()); + this.repositories = this.externalRepositories; + } else { + this.pomRepositories = pomRepositories; + this.externalRepositories = externalRepositories; + this.repositories = repositories; + } this.result.getProblems().forEach(p -> severities.add(p.getSeverity())); } @@ -314,7 +309,15 @@ public DefaultModelBuilderSession derive(ModelBuilderRequest request, DefaultMod throw new IllegalArgumentException("Session mismatch"); } return new DefaultModelBuilderSession( - session, request, result, cache, dag, modelByPath, modelByGA, mappedSources, repositoryHolder); + session, + request, + result, + cache, + dag, + mappedSources, + pomRepositories, + externalRepositories, + repositories); } public Session session() { @@ -342,74 +345,7 @@ public String toString() { + cache + ']'; } - static class Holder { - private volatile boolean set; - private volatile Model model; - - Holder(Model model) { - this.model = requireNonNull(model); - this.set = true; - } - - public static Model deref(Holder holder) { - return holder != null ? holder.get() : null; - } - - public Model get() { - if (!set) { - synchronized (this) { - if (!set) { - try { - this.wait(); - } catch (InterruptedException e) { - // Ignore - } - } - } - } - return model; - } - - public Model computeIfAbsent(Supplier supplier) { - if (!set) { - synchronized (this) { - if (!set) { - this.set = true; - this.model = supplier.get(); - this.notifyAll(); - } - } - } - return model; - } - } - - public Model getRawModel(Path from, String gId, String aId) { - Model model = findRawModel(from, gId, aId); - if (model != null) { - modelByGA.put(new GAKey(gId, aId), new Holder(model)); - if (model.getPomFile() != null) { - modelByPath.put(model.getPomFile(), new Holder(model)); - } - } - return model; - } - - public Model getRawModel(Path from, Path path) { - Model model = findRawModel(from, path); - if (model != null) { - String groupId = getGroupId(model); - modelByGA.put(new GAKey(groupId, model.getArtifactId()), new Holder(model)); - modelByPath.put(path, new Holder(model)); - } - return model; - } - - public Path locate(Path path) { - return getModelProcessor().locateExistingPom(path); - } - - private Model findRawModel(Path from, String groupId, String artifactId) { + public Model getRawModel(Path from, String groupId, String artifactId) { ModelSource source = getSource(groupId, artifactId); if (source == null) { // we need to check the whole reactor in case it's a dependency @@ -429,6 +365,21 @@ private Model findRawModel(Path from, String groupId, String artifactId) { return null; } + public Model getRawModel(Path from, Path path) { + if (!Files.isRegularFile(path)) { + throw new IllegalArgumentException("Not a regular file: " + path); + } + if (!addEdge(from, path)) { + return null; + } + try { + return readRawModel(derive(ModelSource.fromPath(path))); + } catch (ModelBuilderException e) { + // gathered with problem collector + } + return null; + } + private void loadFullReactor() { if (!fullReactorLoaded) { synchronized (this) { @@ -473,21 +424,6 @@ private void doLoadFullReactor() { } } - private Model findRawModel(Path from, Path p) { - if (!Files.isRegularFile(p)) { - throw new IllegalArgumentException("Not a regular file: " + p); - } - if (!addEdge(from, p)) { - return null; - } - try { - return readRawModel(derive(ModelSource.fromPath(p))); - } catch (ModelBuilderException e) { - // gathered with problem collector - } - return null; - } - private boolean addEdge(Path from, Path p) { try { dag.addEdge(from.toString(), p.toString()); @@ -667,75 +603,78 @@ public ModelBuilderException newModelBuilderException() { return new ModelBuilderException(result); } - List getRepositories() { - return repositoryHolder.getRepositories(); - } - - void mergeRepositories(List repositories, boolean replace) { - repositoryHolder.mergeRepositories(repositories, replace); + public List getRepositories() { + return repositories; } - class RepositoryHolder { + /** + * TODO: this is not thread safe and the session is mutated + */ + public void mergeRepositories(List toAdd, boolean replace) { + List repos = + toAdd.stream().map(session::createRemoteRepository).toList(); + if (replace) { + Set ids = repos.stream().map(RemoteRepository::getId).collect(Collectors.toSet()); + repositories = repositories.stream() + .filter(r -> !ids.contains(r.getId())) + .toList(); + pomRepositories = pomRepositories.stream() + .filter(r -> !ids.contains(r.getId())) + .toList(); + } else { + Set ids = + pomRepositories.stream().map(RemoteRepository::getId).collect(Collectors.toSet()); + repos = repos.stream().filter(r -> !ids.contains(r.getId())).toList(); + } - List pomRepositories; - List repositories; - List externalRepositories; + RepositoryFactory repositoryFactory = session.getService(RepositoryFactory.class); + if (request.getRepositoryMerging() == ModelBuilderRequest.RepositoryMerging.REQUEST_DOMINANT) { + repositories = repositoryFactory.aggregate(session, repositories, repos, true); + pomRepositories = repositories; + } else { + pomRepositories = repositoryFactory.aggregate(session, pomRepositories, repos, true); + repositories = repositoryFactory.aggregate(session, pomRepositories, externalRepositories, false); + } + } - RepositoryHolder(List externalRepositories) { - this.pomRepositories = List.of(); - this.externalRepositories = List.copyOf(externalRepositories); - this.repositories = List.copyOf(externalRepositories); - } - - RepositoryHolder(RepositoryHolder holder) { - this.pomRepositories = List.copyOf(holder.pomRepositories); - this.externalRepositories = List.copyOf(holder.externalRepositories); - this.repositories = List.copyOf(holder.repositories); - } - - public void mergeRepositories(List toAdd, boolean replace) { - List repos = - toAdd.stream().map(session::createRemoteRepository).toList(); - if (replace) { - Set ids = - repos.stream().map(RemoteRepository::getId).collect(Collectors.toSet()); - repositories = repositories.stream() - .filter(r -> !ids.contains(r.getId())) - .toList(); - pomRepositories = pomRepositories.stream() - .filter(r -> !ids.contains(r.getId())) - .toList(); - } else { - Set ids = pomRepositories.stream() - .map(RemoteRepository::getId) - .collect(Collectors.toSet()); - repos = repos.stream().filter(r -> !ids.contains(r.getId())).toList(); - } + /** + * ModelSourceTransformer for the build pom + * + * @param model + * @param path + */ + public Model transform(Model model, Path path) { + Model.Builder builder = Model.newBuilder(model); + handleReactorDependencies(model, path, builder); + return builder.build(); + } - RepositoryFactory repositoryFactory = session.getService(RepositoryFactory.class); - if (request.getRepositoryMerging() == ModelBuilderRequest.RepositoryMerging.REQUEST_DOMINANT) { - repositories = repositoryFactory.aggregate(session, repositories, repos, true); - pomRepositories = repositories; - } else { - pomRepositories = repositoryFactory.aggregate(session, pomRepositories, repos, true); - repositories = repositoryFactory.aggregate(session, pomRepositories, externalRepositories, false); + // + // Infer inner reactor dependencies version + // + void handleReactorDependencies(Model model, Path pomFile, Model.Builder builder) { + List newDeps = new ArrayList<>(); + boolean modified = false; + for (Dependency dep : model.getDependencies()) { + if (dep.getVersion() == null) { + Model depModel = getRawModel(model.getPomFile(), dep.getGroupId(), dep.getArtifactId()); + if (depModel != null) { + String v = depModel.getVersion(); + if (v == null && depModel.getParent() != null) { + v = depModel.getParent().getVersion(); + } + dep = dep.withVersion(v); + modified = true; + } } + newDeps.add(dep); } - - public List getRepositories() { - return repositories; - } - - public RepositoryHolder copy() { - return new RepositoryHolder(this); + if (modified) { + builder.dependencies(newDeps); } } } - DefaultModelProblemCollector newCollector(DefaultModelBuilderResult result) { - return new DefaultModelProblemCollector(result); - } - private static ModelBuilderRequest fillRequestDefaults(ModelBuilderRequest request) { ModelBuilderRequest.ModelBuilderRequestBuilder builder = ModelBuilderRequest.builder(request); if (request.getModelResolver() == null) { @@ -1309,7 +1248,7 @@ private Model doReadFileModel(DefaultModelBuilderSession build) throws ModelBuil request, build); if (hasFatalErrors(build)) { - throw ((ModelProblemCollector) build).newModelBuilderException(); + throw build.newModelBuilderException(); } return model; @@ -1327,7 +1266,7 @@ private Model doReadRawModel(DefaultModelBuilderSession build) throws ModelBuild && request.getRequestType() == ModelBuilderRequest.RequestType.BUILD_POM) { Path pomFile = modelSource.getPath(); try { - rawModel = this.transform(build, rawModel, pomFile); + rawModel = build.transform(rawModel, pomFile); } catch (ModelTransformerException e) { build.add(Severity.FATAL, ModelProblem.Version.V40, null, e); } @@ -2015,68 +1954,21 @@ private static ModelResolver getModelResolver(ModelBuilderRequest request) { return request.getModelResolver(); } - /** - * ModelSourceTransformer for the build pom - */ - Model transform(DefaultModelBuilderSession build, Model model, Path path) { - Model.Builder builder = Model.newBuilder(model); - handleReactorDependencies(build, model, path, builder); - return builder.build(); - } - - // - // Infer inner reactor dependencies version - // - void handleReactorDependencies(DefaultModelBuilderSession build, Model model, Path pomFile, Model.Builder builder) { - List newDeps = new ArrayList<>(); - boolean modified = false; - for (Dependency dep : model.getDependencies()) { - Dependency.Builder depBuilder = null; - if (dep.getVersion() == null) { - Model depModel = build.getRawModel(model.getPomFile(), dep.getGroupId(), dep.getArtifactId()); - if (depModel != null) { - String version = depModel.getVersion(); - InputLocation versionLocation = depModel.getLocation("version"); - if (version == null && depModel.getParent() != null) { - version = depModel.getParent().getVersion(); - versionLocation = depModel.getParent().getLocation("version"); - } - depBuilder = Dependency.newBuilder(dep); - depBuilder.version(version).location("version", versionLocation); - if (dep.getGroupId() == null) { - String depGroupId = depModel.getGroupId(); - InputLocation groupIdLocation = depModel.getLocation("groupId"); - if (depGroupId == null && depModel.getParent() != null) { - depGroupId = depModel.getParent().getGroupId(); - groupIdLocation = depModel.getParent().getLocation("groupId"); - } - depBuilder.groupId(depGroupId).location("groupId", groupIdLocation); - } - } - } - if (depBuilder != null) { - newDeps.add(depBuilder.build()); - modified = true; - } else { - newDeps.add(dep); - } - } - if (modified) { - builder.dependencies(newDeps); + private static RelativeProject toRelativeProject(final Model m) { + String groupId = m.getGroupId(); + if (groupId == null && m.getParent() != null) { + groupId = m.getParent().getGroupId(); } - } - String replaceCiFriendlyVersion(DefaultModelBuilderSession build, String version) { - if (version != null) { - for (String key : Arrays.asList("changelist", "revision", "sha1")) { - String val = build.request.getUserProperties().get(key); - if (val != null) { - version = version.replace("${" + key + "}", val); - } - } + String version = m.getVersion(); + if (version == null && m.getParent() != null) { + version = m.getParent().getVersion(); } - return version; + + return new RelativeProject(groupId, m.getArtifactId(), version); } + protected record RelativeProject(String groupId, String artifactId, String version) {} + record GAKey(String groupId, String artifactId) {} }