Skip to content

Commit f1b7bf2

Browse files
committed
A few improvements
* change ModelParser to return an Optional<Source> instead of Path * add a ModelParser@locateAndParse method * move located pom existence check into a ModelLocator#locateExistingPom This abstract the "pom.xml" file notion a bit more
1 parent 97c11dd commit f1b7bf2

File tree

14 files changed

+170
-57
lines changed

14 files changed

+170
-57
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.maven.api.services;
20+
21+
import java.io.IOException;
22+
import java.io.InputStream;
23+
import java.nio.file.Files;
24+
import java.nio.file.Path;
25+
import java.util.Objects;
26+
27+
import org.apache.maven.api.annotations.Nonnull;
28+
29+
public class PathSource implements Source {
30+
31+
private final Path path;
32+
33+
public PathSource(@Nonnull Path path) {
34+
this.path = Objects.requireNonNull(path);
35+
}
36+
37+
@Nonnull
38+
@Override
39+
public Path getPath() {
40+
return path;
41+
}
42+
43+
@Nonnull
44+
@Override
45+
public InputStream getInputStream() throws IOException {
46+
return Files.newInputStream(path);
47+
}
48+
49+
@Nonnull
50+
@Override
51+
public String getLocation() {
52+
return path.toString();
53+
}
54+
}

api/maven-api-spi/src/main/java/org/apache/maven/api/spi/ModelParser.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import java.nio.file.Path;
2222
import java.util.Map;
23+
import java.util.Optional;
2324

2425
import org.apache.maven.api.annotations.Experimental;
2526
import org.apache.maven.api.annotations.Nonnull;
@@ -40,16 +41,31 @@ public interface ModelParser {
4041
* @param dir the directory to locate the pom for, never {@code null}
4142
* @return the located pom or <code>null</code> if none was found by this parser
4243
*/
43-
@Nullable
44-
Path locatePom(@Nonnull Path dir);
44+
@Nonnull
45+
Optional<Source> locate(@Nonnull Path dir);
4546

4647
/**
4748
* Parse the model.
4849
*
4950
* @param source the source to parse, never {@code null}
51+
* @param options possible parsing options, may be {@code null}
5052
* @return the parsed {@link Model}, never {@code null}
5153
* @throws ModelParserException if the model cannot be parsed
5254
*/
5355
@Nonnull
54-
Model parse(@Nonnull Source source, Map<String, ?> options) throws ModelParserException;
56+
Model parse(@Nonnull Source source, @Nullable Map<String, ?> options) throws ModelParserException;
57+
58+
/**
59+
* Locate and parse the model in the specified directory.
60+
* This is equivalent to {@code locate(dir).map(s -> parse(s, options))}.
61+
*
62+
* @param dir the directory to locate the pom for, never {@code null}
63+
* @param options possible parsing options, may be {@code null}
64+
* @return an optional parsed {@link Model} or {@code null} if none could be found
65+
* @throws ModelParserException if the located model cannot be parsd
66+
*/
67+
default Optional<Model> locateAndParse(@Nonnull Path dir, @Nullable Map<String, ?> options)
68+
throws ModelParserException {
69+
return locate(dir).map(s -> parse(s, options));
70+
}
5571
}

maven-core/src/main/java/org/apache/maven/internal/transformation/ConsumerPomArtifactTransformer.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@
3939
import java.util.function.BiConsumer;
4040

4141
import org.apache.maven.api.model.Model;
42+
import org.apache.maven.api.services.Source;
4243
import org.apache.maven.api.spi.ModelParser;
4344
import org.apache.maven.feature.Features;
4445
import org.apache.maven.model.building.DefaultBuildPomXMLFilterFactory;
45-
import org.apache.maven.model.building.FileSource;
4646
import org.apache.maven.model.building.TransformerContext;
4747
import org.apache.maven.model.transform.RawToConsumerPomXMLFilterFactory;
4848
import org.apache.maven.model.transform.stax.XmlUtils;
@@ -196,13 +196,19 @@ BiConsumer<Path, Path> transformer(RepositorySystemSession session) {
196196
* The actual transformation: visible for testing.
197197
*/
198198
void transform(Path pomFile, Path destPomFile, TransformerContext context) throws IOException, XMLStreamException {
199-
ModelParser parser = modelParsers.values().stream()
200-
.filter(p -> pomFile.equals(p.locatePom(pomFile.getParent())))
201-
.findAny()
202-
.orElse(null);
203-
if (parser != null) {
199+
ModelParser parser = null;
200+
Source source = null;
201+
for (ModelParser p : modelParsers.values()) {
202+
source = p.locate(pomFile).orElse(null);
203+
if (source != null) {
204+
parser = p;
205+
break;
206+
}
207+
}
208+
209+
if (source != null) {
204210
try (OutputStream output = Files.newOutputStream(destPomFile)) {
205-
Model model = parser.parse(new FileSource(pomFile), null);
211+
Model model = parser.parse(source, null);
206212
// transform
207213
model = model.withRoot(false).withModules(null);
208214
if (model.getParent() != null) {

maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -497,15 +497,11 @@ private boolean build(
497497

498498
module = module.replace('\\', File.separatorChar).replace('/', File.separatorChar);
499499

500-
File moduleFile = new File(basedir, module);
500+
File moduleFile = modelProcessor.locateExistingPom(new File(basedir, module));
501501

502-
if (moduleFile.isDirectory()) {
503-
moduleFile = modelProcessor.locatePom(moduleFile);
504-
}
505-
506-
if (!moduleFile.isFile()) {
502+
if (moduleFile == null) {
507503
ModelProblem problem = new DefaultModelProblem(
508-
"Child module " + moduleFile + " of " + pomFile + " does not exist",
504+
"Child module " + module + " of " + pomFile + " does not exist",
509505
ModelProblem.Severity.ERROR,
510506
ModelProblem.Version.BASE,
511507
model,

maven-core/src/main/java/org/apache/maven/project/collector/MultiModuleCollectionStrategy.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,16 @@ public List<MavenProject> collectProjects(MavenExecutionRequest request) throws
9797
}
9898

9999
private File getMultiModuleProjectPomFile(MavenExecutionRequest request) {
100-
if (request.getPom().getParentFile().equals(request.getMultiModuleProjectDirectory())) {
100+
File multiModuleProjectDirectory = request.getMultiModuleProjectDirectory();
101+
if (request.getPom().getParentFile().equals(multiModuleProjectDirectory)) {
101102
return request.getPom();
102103
} else {
103-
File multiModuleProjectPom = modelLocator.locatePom(request.getMultiModuleProjectDirectory());
104-
if (!multiModuleProjectPom.exists()) {
104+
File multiModuleProjectPom = modelLocator.locateExistingPom(multiModuleProjectDirectory);
105+
if (multiModuleProjectPom == null) {
105106
LOGGER.info(
106107
"Maven detected that the requested POM file is part of a multi-module project, "
107108
+ "but could not find a pom.xml file in the multi-module root directory '{}'.",
108-
request.getMultiModuleProjectDirectory());
109+
multiModuleProjectDirectory);
109110
LOGGER.info("The reactor is limited to all projects under: "
110111
+ request.getPom().getParent());
111112
return request.getPom();

maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,18 +1354,11 @@ private File determinePom(final CommandLine commandLine, final String workingDir
13541354
current = resolveFile(new File(alternatePomFile), workingDirectory);
13551355
}
13561356

1357-
File pom;
1358-
if (current.isDirectory() && modelProcessor != null) {
1359-
pom = modelProcessor.locatePom(current);
1357+
if (modelProcessor != null) {
1358+
return modelProcessor.locateExistingPom(current);
13601359
} else {
1361-
pom = current;
1360+
return current.isFile() ? current : null;
13621361
}
1363-
1364-
if (pom.isFile()) {
1365-
return pom;
1366-
}
1367-
1368-
return null;
13691362
}
13701363

13711364
// Visible for testing

maven-model-builder/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ under the License.
142142
<exclude>org.apache.maven.model.interpolation.StringSearchModelInterpolator</exclude>
143143
<exclude>org.apache.maven.model.interpolation.StringVisitorModelInterpolator</exclude>
144144
<exclude>org.apache.maven.model.io.DefaultModelReader#DefaultModelReader():CONSTRUCTOR_REMOVED</exclude>
145+
<exclude>org.apache.maven.model.locator.ModelLocator#locateExistingPom(java.io.File):METHOD_NEW_DEFAULT</exclude>
145146
<exclude>org.apache.maven.model.management.DefaultDependencyManagementInjector$ManagementModelMerger</exclude>
146147
<exclude>org.apache.maven.model.management.DefaultPluginManagementInjector$ManagementModelMerger</exclude>
147148
<exclude>org.apache.maven.model.merge.MavenModelMerger</exclude>

maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1888,7 +1888,8 @@ public TransformerContext initialize(ModelBuildingRequest request, ModelProblemC
18881888
return new TransformerContext() {
18891889
@Override
18901890
public Path locate(Path path) {
1891-
return modelProcessor.locatePom(path.toFile()).toPath();
1891+
File file = modelProcessor.locateExistingPom(path.toFile());
1892+
return file != null ? file.toPath() : null;
18921893
}
18931894

18941895
@Override

maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,13 @@
2626
import java.io.IOException;
2727
import java.io.InputStream;
2828
import java.io.Reader;
29-
import java.nio.file.Files;
3029
import java.nio.file.Path;
3130
import java.util.ArrayList;
3231
import java.util.Collection;
3332
import java.util.List;
3433
import java.util.Map;
3534
import java.util.Objects;
36-
import java.util.stream.Collectors;
35+
import java.util.Optional;
3736

3837
import org.apache.maven.api.model.Model;
3938
import org.apache.maven.api.spi.ModelParser;
@@ -95,13 +94,36 @@ public Path locatePom(Path projectDirectory) {
9594
// Note that the ModelProcessor#locatePom never returns null
9695
// while the ModelParser#locatePom needs to return an existing path!
9796
Path pom = modelParsers.stream()
98-
.map(m -> m.locatePom(projectDirectory))
97+
.map(m -> m.locate(projectDirectory)
98+
.map(org.apache.maven.api.services.Source::getPath)
99+
.orElse(null))
99100
.filter(Objects::nonNull)
100-
.filter(Files::exists)
101101
.findFirst()
102102
.orElseGet(
103103
() -> modelLocator.locatePom(projectDirectory.toFile()).toPath());
104-
if (!pom.getParent().equals(projectDirectory)) {
104+
if (!pom.equals(projectDirectory) && !pom.getParent().equals(projectDirectory)) {
105+
throw new IllegalArgumentException("The POM found does not belong to the given directory: " + pom);
106+
}
107+
return pom;
108+
}
109+
110+
public File locateExistingPom(File projectDirectory) {
111+
Path path = locateExistingPom(projectDirectory.toPath());
112+
return path != null ? path.toFile() : null;
113+
}
114+
115+
public Path locateExistingPom(Path projectDirectory) {
116+
// Note that the ModelProcessor#locatePom never returns null
117+
// while the ModelParser#locatePom needs to return an existing path!
118+
Path pom = modelParsers.stream()
119+
.map(m -> m.locate(projectDirectory).map(s -> s.getPath()).orElse(null))
120+
.filter(Objects::nonNull)
121+
.findFirst()
122+
.orElseGet(() -> {
123+
File f = modelLocator.locateExistingPom(projectDirectory.toFile());
124+
return f != null ? f.toPath() : null;
125+
});
126+
if (pom != null && !pom.equals(projectDirectory) && !pom.getParent().equals(projectDirectory)) {
105127
throw new IllegalArgumentException("The POM found does not belong to the given directory: " + pom);
106128
}
107129
return pom;
@@ -118,15 +140,17 @@ protected org.apache.maven.api.model.Model read(
118140
}
119141
if (pomFile != null) {
120142
Path projectDirectory = pomFile.getParent();
121-
Path path = pomFile;
122-
List<ModelParser> parsers = modelParsers.stream()
123-
.filter(p -> path.equals(p.locatePom(projectDirectory)))
124-
.collect(Collectors.toList());
143+
// Path path = pomFile;
144+
// List<ModelParser> parsers = modelParsers.stream()
145+
// .filter(p -> path.equals(p.locatePom(projectDirectory)))
146+
// .collect(Collectors.toList());
125147
List<ModelParserException> exceptions = new ArrayList<>();
126-
for (ModelParser parser : parsers) {
148+
for (ModelParser parser : modelParsers) {
127149
try {
128-
Model model = parser.parse(new FileSource(pomFile), options);
129-
return model.withPomFile(pomFile);
150+
Optional<Model> model = parser.locateAndParse(projectDirectory, options);
151+
if (model.isPresent()) {
152+
return model.get().withPomFile(pomFile);
153+
}
130154
} catch (ModelParserException e) {
131155
exceptions.add(e);
132156
}

maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContext.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package org.apache.maven.model.building;
2020

21+
import java.io.File;
2122
import java.nio.file.Path;
2223
import java.util.Map;
2324
import java.util.Objects;
@@ -101,7 +102,8 @@ public Model getRawModel(String groupId, String artifactId) {
101102

102103
@Override
103104
public Path locate(Path path) {
104-
return modelLocator.locatePom(path.toFile()).toPath();
105+
File file = modelLocator.locateExistingPom(path.toFile());
106+
return file != null ? file.toPath() : null;
105107
}
106108

107109
static class GAKey {

0 commit comments

Comments
 (0)