in impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java [1225:1429]
Model doReadFileModel() throws ModelBuilderException {
ModelSource modelSource = request.getSource();
Model model;
Path rootDirectory;
setSource(modelSource.getLocation());
logger.debug("Reading file model from " + modelSource.getLocation());
try {
boolean strict = isBuildRequest();
try {
rootDirectory = request.getSession().getRootDirectory();
} catch (IllegalStateException ignore) {
rootDirectory = modelSource.getPath();
while (rootDirectory != null && !Files.isDirectory(rootDirectory)) {
rootDirectory = rootDirectory.getParent();
}
}
try (InputStream is = modelSource.openStream()) {
model = modelProcessor.read(XmlReaderRequest.builder()
.strict(strict)
.location(modelSource.getLocation())
.path(modelSource.getPath())
.rootDirectory(rootDirectory)
.inputStream(is)
.transformer(new InliningTransformer())
.build());
} catch (XmlReaderException e) {
if (!strict) {
throw e;
}
try (InputStream is = modelSource.openStream()) {
model = modelProcessor.read(XmlReaderRequest.builder()
.strict(false)
.location(modelSource.getLocation())
.path(modelSource.getPath())
.rootDirectory(rootDirectory)
.inputStream(is)
.transformer(new InliningTransformer())
.build());
} catch (XmlReaderException ne) {
// still unreadable even in non-strict mode, rethrow original error
throw e;
}
add(
Severity.ERROR,
Version.V20,
"Malformed POM " + modelSource.getLocation() + ": " + e.getMessage(),
e);
}
InputLocation loc = model.getLocation("");
InputSource v4src = loc != null ? loc.getSource() : null;
if (v4src != null) {
try {
Field field = InputSource.class.getDeclaredField("modelId");
field.setAccessible(true);
field.set(v4src, ModelProblemUtils.toId(model));
} catch (Throwable t) {
// TODO: use a lazy source ?
throw new IllegalStateException("Unable to set modelId on InputSource", t);
}
}
} catch (XmlReaderException e) {
add(
Severity.FATAL,
Version.BASE,
"Non-parseable POM " + modelSource.getLocation() + ": " + e.getMessage(),
e);
throw newModelBuilderException();
} catch (IOException e) {
String msg = e.getMessage();
if (msg == null || msg.isEmpty()) {
// NOTE: There's java.nio.charset.MalformedInputException and sun.io.MalformedInputException
if (e.getClass().getName().endsWith("MalformedInputException")) {
msg = "Some input bytes do not match the file encoding.";
} else {
msg = e.getClass().getSimpleName();
}
}
add(Severity.FATAL, Version.BASE, "Non-readable POM " + modelSource.getLocation() + ": " + msg, e);
throw newModelBuilderException();
}
if (model.getModelVersion() == null) {
String namespace = model.getNamespaceUri();
if (namespace != null && namespace.startsWith(NAMESPACE_PREFIX)) {
model = model.withModelVersion(namespace.substring(NAMESPACE_PREFIX.length()));
}
}
if (isBuildRequest()) {
model = model.withPomFile(modelSource.getPath());
Parent parent = model.getParent();
if (parent != null) {
String groupId = parent.getGroupId();
String artifactId = parent.getArtifactId();
String version = parent.getVersion();
String path = parent.getRelativePath();
if ((groupId == null || artifactId == null || version == null)
&& (path == null || !path.isEmpty())) {
Path pomFile = model.getPomFile();
Path relativePath = Paths.get(path != null ? path : "..");
Path pomPath = pomFile.resolveSibling(relativePath).normalize();
if (Files.isDirectory(pomPath)) {
pomPath = modelProcessor.locateExistingPom(pomPath);
}
if (pomPath != null && Files.isRegularFile(pomPath)) {
Model parentModel =
derive(Sources.buildSource(pomPath)).readFileModel();
String parentGroupId = getGroupId(parentModel);
String parentArtifactId = parentModel.getArtifactId();
String parentVersion = getVersion(parentModel);
if ((groupId == null || groupId.equals(parentGroupId))
&& (artifactId == null || artifactId.equals(parentArtifactId))
&& (version == null || version.equals(parentVersion))) {
model = model.withParent(parent.with()
.groupId(parentGroupId)
.artifactId(parentArtifactId)
.version(parentVersion)
.build());
} else {
mismatchRelativePathAndGA(model, parentGroupId, parentArtifactId);
}
} else {
if (!MODEL_VERSION_4_0_0.equals(model.getModelVersion()) && path != null) {
wrongParentRelativePath(model);
}
}
}
}
// subprojects discovery
if (getSubprojects(model).isEmpty()
// only discover subprojects if POM > 4.0.0
&& !MODEL_VERSION_4_0_0.equals(model.getModelVersion())
// and if packaging is POM (we check type, but the session is not yet available,
// we would require the project realm if we want to support extensions
&& Type.POM.equals(model.getPackaging())) {
List<String> subprojects = new ArrayList<>();
try (Stream<Path> files = Files.list(model.getProjectDirectory())) {
for (Path f : files.toList()) {
if (Files.isDirectory(f)) {
Path subproject = modelProcessor.locateExistingPom(f);
if (subproject != null) {
subprojects.add(f.getFileName().toString());
}
}
}
if (!subprojects.isEmpty()) {
model = model.withSubprojects(subprojects);
}
} catch (IOException e) {
add(Severity.FATAL, Version.V41, "Error discovering subprojects", e);
}
}
// CI friendly version
// All expressions are interpolated using user properties and properties
// defined on the root project.
Map<String, String> properties = new HashMap<>();
if (!Objects.equals(rootDirectory, model.getProjectDirectory())) {
Path rootModelPath = modelProcessor.locateExistingPom(rootDirectory);
if (rootModelPath != null) {
Model rootModel =
derive(Sources.buildSource(rootModelPath)).readFileModel();
properties.putAll(rootModel.getProperties());
}
} else {
properties.putAll(model.getProperties());
}
properties.putAll(session.getUserProperties());
model = model.with()
.version(replaceCiFriendlyVersion(properties, model.getVersion()))
.parent(
model.getParent() != null
? model.getParent()
.withVersion(replaceCiFriendlyVersion(
properties,
model.getParent().getVersion()))
: null)
.build();
// Override model properties with user properties
Map<String, String> newProps = merge(model.getProperties(), session.getUserProperties());
if (newProps != null) {
model = model.withProperties(newProps);
}
model = model.withProfiles(merge(model.getProfiles(), session.getUserProperties()));
}
for (var transformer : transformers) {
model = transformer.transformFileModel(model);
}
setSource(model);
modelValidator.validateFileModel(
model,
isBuildRequest() ? ModelValidator.VALIDATION_LEVEL_STRICT : ModelValidator.VALIDATION_LEVEL_MINIMAL,
this);
if (hasFatalErrors()) {
throw newModelBuilderException();
}
return model;
}