diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java index 1e1568e819..6b52e4eade 100644 --- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java +++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java @@ -497,15 +497,11 @@ public class DefaultProjectBuilder implements ProjectBuilder { module = module.replace('\\', File.separatorChar).replace('/', File.separatorChar); - File moduleFile = new File(basedir, module); + File moduleFile = modelProcessor.locateExistingPom(new File(basedir, module)); - if (moduleFile.isDirectory()) { - moduleFile = modelProcessor.locatePom(moduleFile); - } - - if (!moduleFile.isFile()) { + if (moduleFile == null) { ModelProblem problem = new DefaultModelProblem( - "Child module " + moduleFile + " of " + pomFile + " does not exist", + "Child module " + module + " of " + pomFile + " does not exist", ModelProblem.Severity.ERROR, ModelProblem.Version.BASE, model, diff --git a/maven-core/src/main/java/org/apache/maven/project/collector/MultiModuleCollectionStrategy.java b/maven-core/src/main/java/org/apache/maven/project/collector/MultiModuleCollectionStrategy.java index fa38120f49..9f81694d40 100644 --- a/maven-core/src/main/java/org/apache/maven/project/collector/MultiModuleCollectionStrategy.java +++ b/maven-core/src/main/java/org/apache/maven/project/collector/MultiModuleCollectionStrategy.java @@ -97,15 +97,16 @@ public class MultiModuleCollectionStrategy implements ProjectCollectionStrategy } private File getMultiModuleProjectPomFile(MavenExecutionRequest request) { - if (request.getPom().getParentFile().equals(request.getMultiModuleProjectDirectory())) { + File multiModuleProjectDirectory = request.getMultiModuleProjectDirectory(); + if (request.getPom().getParentFile().equals(multiModuleProjectDirectory)) { return request.getPom(); } else { - File multiModuleProjectPom = modelLocator.locatePom(request.getMultiModuleProjectDirectory()); - if (!multiModuleProjectPom.exists()) { + File multiModuleProjectPom = modelLocator.locateExistingPom(multiModuleProjectDirectory); + if (multiModuleProjectPom == null) { LOGGER.info( "Maven detected that the requested POM file is part of a multi-module project, " + "but could not find a pom.xml file in the multi-module root directory '{}'.", - request.getMultiModuleProjectDirectory()); + multiModuleProjectDirectory); LOGGER.info("The reactor is limited to all projects under: " + request.getPom().getParent()); return request.getPom(); diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index a1b6e032b5..99cf7dcf2c 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -1354,18 +1354,11 @@ public class MavenCli { current = resolveFile(new File(alternatePomFile), workingDirectory); } - File pom; - if (current.isDirectory() && modelProcessor != null) { - pom = modelProcessor.locatePom(current); + if (modelProcessor != null) { + return modelProcessor.locateExistingPom(current); } else { - pom = current; + return current.isFile() ? current : null; } - - if (pom.isFile()) { - return pom; - } - - return null; } // Visible for testing diff --git a/maven-model-builder/pom.xml b/maven-model-builder/pom.xml index 6e2975dd3b..dccf9056f9 100644 --- a/maven-model-builder/pom.xml +++ b/maven-model-builder/pom.xml @@ -144,6 +144,7 @@ under the License. org.apache.maven.model.interpolation.StringSearchModelInterpolator org.apache.maven.model.interpolation.StringVisitorModelInterpolator org.apache.maven.model.io.DefaultModelReader#DefaultModelReader():CONSTRUCTOR_REMOVED + org.apache.maven.model.locator.ModelLocator#locateExistingPom(java.io.File):METHOD_NEW_DEFAULT org.apache.maven.model.management.DefaultDependencyManagementInjector$ManagementModelMerger org.apache.maven.model.management.DefaultPluginManagementInjector$ManagementModelMerger org.apache.maven.model.merge.MavenModelMerger diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java index 9502c49ae0..ed76d6065c 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java @@ -1894,7 +1894,8 @@ public class DefaultModelBuilder implements ModelBuilder { return new TransformerContext() { @Override public Path locate(Path path) { - return modelProcessor.locatePom(path.toFile()).toPath(); + File file = modelProcessor.locateExistingPom(path.toFile()); + return file != null ? file.toPath() : null; } @Override diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java index 916e80d42d..26eb70bb48 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java @@ -26,9 +26,11 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.Reader; +import java.nio.file.Path; import java.util.Map; +import java.util.Objects; -import org.apache.maven.model.Model; +import org.apache.maven.building.Source; import org.apache.maven.model.io.ModelReader; import org.apache.maven.model.locator.ModelLocator; import org.eclipse.sisu.Typed; @@ -63,32 +65,88 @@ import org.eclipse.sisu.Typed; @Typed(ModelProcessor.class) public class DefaultModelProcessor implements ModelProcessor { - private final ModelLocator locator; - private final ModelReader reader; + private final ModelLocator modelLocator; + private final ModelReader modelReader; @Inject - public DefaultModelProcessor(ModelLocator locator, ModelReader reader) { - this.locator = locator; - this.reader = reader; + public DefaultModelProcessor(ModelLocator modelLocator, ModelReader modelReader) { + this.modelLocator = modelLocator; + this.modelReader = modelReader; } @Override public File locatePom(File projectDirectory) { - return locator.locatePom(projectDirectory); + return locatePom(projectDirectory.toPath()).toFile(); + } + + public Path locatePom(Path projectDirectory) { + // Note that the ModelProcessor#locatePom never returns null + // while the ModelParser#locatePom needs to return an existing path! + Path pom = modelLocator.locatePom(projectDirectory.toFile()).toPath(); + if (!pom.equals(projectDirectory) && !pom.getParent().equals(projectDirectory)) { + throw new IllegalArgumentException("The POM found does not belong to the given directory: " + pom); + } + return pom; + } + + public File locateExistingPom(File projectDirectory) { + Path path = locateExistingPom(projectDirectory.toPath()); + return path != null ? path.toFile() : null; + } + + public Path locateExistingPom(Path projectDirectory) { + // Note that the ModelProcessor#locatePom never returns null + File f = modelLocator.locateExistingPom(projectDirectory.toFile()); + Path pom = f != null ? f.toPath() : null; + if (pom != null && !pom.equals(projectDirectory) && !pom.getParent().equals(projectDirectory)) { + throw new IllegalArgumentException("The POM found does not belong to the given directory: " + pom); + } + return pom; + } + + protected org.apache.maven.api.model.Model read( + Path pomFile, InputStream input, Reader reader, Map options) throws IOException { + Source source = (Source) options.get(ModelProcessor.SOURCE); + if (pomFile == null && source instanceof org.apache.maven.building.FileSource) { + pomFile = ((org.apache.maven.building.FileSource) source).getFile().toPath(); + } + return readXmlModel(pomFile, input, reader, options); + } + + private org.apache.maven.api.model.Model readXmlModel( + Path pomFile, InputStream input, Reader reader, Map options) throws IOException { + if (pomFile != null) { + return modelReader.read(pomFile.toFile(), options).getDelegate(); + } else if (input != null) { + return modelReader.read(input, options).getDelegate(); + } else { + return modelReader.read(reader, options).getDelegate(); + } } @Override - public Model read(File input, Map options) throws IOException { - return reader.read(input, options); + public org.apache.maven.model.Model read(File file, Map options) throws IOException { + Objects.requireNonNull(file, "file cannot be null"); + Path path = file.toPath(); + org.apache.maven.api.model.Model model = read(path, null, null, options); + return new org.apache.maven.model.Model(model); } @Override - public Model read(Reader input, Map options) throws IOException { - return reader.read(input, options); + public org.apache.maven.model.Model read(InputStream input, Map options) throws IOException { + Objects.requireNonNull(input, "input cannot be null"); + try (InputStream in = input) { + org.apache.maven.api.model.Model model = read(null, in, null, options); + return new org.apache.maven.model.Model(model); + } } @Override - public Model read(InputStream input, Map options) throws IOException { - return reader.read(input, options); + public org.apache.maven.model.Model read(Reader reader, Map options) throws IOException { + Objects.requireNonNull(reader, "reader cannot be null"); + try (Reader r = reader) { + org.apache.maven.api.model.Model model = read(null, null, r, options); + return new org.apache.maven.model.Model(model); + } } } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContext.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContext.java index b933df316f..1497b128b3 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContext.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContext.java @@ -18,6 +18,7 @@ */ package org.apache.maven.model.building; +import java.io.File; import java.nio.file.Path; import java.util.Map; import java.util.Objects; @@ -100,7 +101,8 @@ class DefaultTransformerContext implements TransformerContext { @Override public Path locate(Path path) { - return modelLocator.locatePom(path.toFile()).toPath(); + File file = modelLocator.locateExistingPom(path.toFile()); + return file != null ? file.toPath() : null; } static class GAKey { diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/FileModelSource.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/FileModelSource.java index 858c42b8a1..5bbf0eb32f 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/FileModelSource.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/FileModelSource.java @@ -54,13 +54,11 @@ public class FileModelSource extends FileSource implements ModelSource3 { public ModelSource3 getRelatedSource(ModelLocator locator, String relPath) { relPath = relPath.replace('\\', File.separatorChar).replace('/', File.separatorChar); - File relatedPom = new File(getFile().getParentFile(), relPath); + File path = new File(getFile().getParentFile(), relPath); - if (relatedPom.isDirectory() && locator != null) { - relatedPom = locator.locatePom(relatedPom); - } + File relatedPom = locator.locateExistingPom(path); - if (relatedPom.isFile() && relatedPom.canRead()) { + if (relatedPom != null) { return new FileModelSource(relatedPom.toPath().normalize().toFile()); } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/locator/DefaultModelLocator.java b/maven-model-builder/src/main/java/org/apache/maven/model/locator/DefaultModelLocator.java index 1a8ab6d760..eb51e75475 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/locator/DefaultModelLocator.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/locator/DefaultModelLocator.java @@ -33,6 +33,21 @@ public class DefaultModelLocator implements ModelLocator { @Override public File locatePom(File projectDirectory) { - return new File(projectDirectory, "pom.xml"); + return projectDirectory != null ? projectDirectory : new File("."); + } + + @Override + public File locateExistingPom(File project) { + if (project == null || project.isDirectory()) { + project = locatePom(project); + } + if (project.isDirectory()) { + File pom = new File(project, "pom.xml"); + return pom.isFile() ? pom : null; + } else if (project.isFile()) { + return project; + } else { + return null; + } } } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/locator/ModelLocator.java b/maven-model-builder/src/main/java/org/apache/maven/model/locator/ModelLocator.java index c187a4d47f..27b073c71d 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/locator/ModelLocator.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/locator/ModelLocator.java @@ -37,4 +37,14 @@ public interface ModelLocator { * @return The path to the (possibly non-existent) POM file, never {@code null}. */ File locatePom(File projectDirectory); + + /** + * Returns the file containing the pom or null if a pom can not be found at the given file or in the given directory. + */ + default File locateExistingPom(File project) { + if (project == null || project.isDirectory()) { + project = locatePom(project); + } + return project.isFile() ? project : null; + } } diff --git a/maven-model-transform/src/main/java/org/apache/maven/model/transform/ParentXMLFilter.java b/maven-model-transform/src/main/java/org/apache/maven/model/transform/ParentXMLFilter.java index 4361bfdf7f..a9cea3d282 100644 --- a/maven-model-transform/src/main/java/org/apache/maven/model/transform/ParentXMLFilter.java +++ b/maven-model-transform/src/main/java/org/apache/maven/model/transform/ParentXMLFilter.java @@ -20,7 +20,6 @@ package org.apache.maven.model.transform; import javax.xml.stream.XMLStreamReader; -import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; @@ -132,12 +131,9 @@ class ParentXMLFilter extends NodeBufferingParser { } protected Optional resolveRelativePath(Path relativePath, String groupId, String artifactId) { - Path pomPath = projectPath.resolve(relativePath).normalize(); - if (Files.isDirectory(pomPath) && modelLocator != null) { - pomPath = modelLocator.apply(pomPath); - } + Path pomPath = modelLocator.apply(projectPath.resolve(relativePath).normalize()); - if (pomPath == null || !Files.isRegularFile(pomPath)) { + if (pomPath == null) { return Optional.empty(); }